如何使用bash清理多个文件名?

问题描述 投票:0回答:3

我有。目录中包含~250 .txt文件。每个文件都有这样的标题:

Abraham Lincoln [December 01, 1862].txt

George Washington [October 25, 1790].txt

等等...

但是,这些是用于读取python的可怕文件名,我想迭代它们以将它们更改为更合适的格式。

我尝试过类似的事情来改变在许多文件中共享的单个变量。但我无法理解如何迭代这些文件并更改其名称的格式,同时仍保留相同的信息。

理想的输出就像是

1861_12_01_abraham_lincoln.txt

1790_10_25_george_washington.txt

等等...

string bash date filenames
3个回答
1
投票

请尝试简单(乏味)的bash脚本:

#!/bin/bash

declare -A map=(["January"]="01" ["February"]="02" ["March"]="03" ["April"]="04" ["May"]="05" ["June"]="06" ["July"]="07" ["August"]="08" ["September"]="09" ["October"]="10" ["November"]="11" ["December"]="12")

pat='^([^[]+) \[([A-Za-z]+) ([0-9]+), ([0-9]+)]\.txt$'
for i in *.txt; do
    if [[ $i =~ $pat ]]; then
        newname="$(printf "%s_%s_%s_%s.txt" "${BASH_REMATCH[4]}" "${map["${BASH_REMATCH[2]}"]}"  "${BASH_REMATCH[3]}" "$(tr 'A-Z ' 'a-z_' <<< "${BASH_REMATCH[1]}")")"
        mv -- "$i" "$newname"
    fi
done

0
投票

我喜欢将文件名分开,然后将其重新组合在一起。

GNU日期也可以解析时间,这比使用sed或大型case语句将“October”转换为“10”更简单。

#! /usr/bin/bash

if [ "$1" == "" ] || [ "$1" == "--help" ]; then
    echo "Give a filename like \"Abraham Lincoln [December 01, 1862].txt\" as an argument"
    exit 2
fi

filename="$1"

# remove the brackets
filename=`echo "$filename" | sed -e 's/[\[]//g;s/\]//g'`

# cut out the name
namepart=`echo "$filename" | awk '{ print $1" "$2 }'`

# cut out the date
datepart=`echo "$filename" | awk '{ print $3" "$4" "$5 }' | sed -e 's/\.txt//'`

# format up the date (relies on GNU date)
datepart=`date --date="$datepart" +"%Y_%m_%d"`

# put it back together with underscores, in lower case
final=`echo "$namepart $datepart.txt" | tr '[A-Z]' '[a-z]' | sed -e 's/ /_/g'`

echo mv \"$1\" \"$final\"

编辑:从Bourne shell转换为BASH。


0
投票
for file in *.txt; do
    # extract parts of the filename to be differently formatted with a regex match
    [[ $file =~ (.*)\[(.*)\] ]] || { echo "invalid file $file"; exit; }

    # format extracted strings and generate the new filename
    formatted_date=$(date -d "${BASH_REMATCH[2]}" +"%Y_%m_%d")
    name="${BASH_REMATCH[1]// /_}"  # replace spaces in the name with underscores
    f="${formatted_date}_${name,,}" # convert name to lower-case and append it to date string
    new_filename="${f::-1}.txt"     # remove trailing underscore and add `.txt` extension

    # do what you need here
    echo $new_filename
    # mv $file $new_filename
done 
© www.soinside.com 2019 - 2024. All rights reserved.