使用 SED 从文件名中提取部分内容

使用 SED 从文件名中提取部分内容

我试图理解这个 sed 命令来将某些内容存储在变量中:

username=$(find . -iname '*.txt' | sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1./i' | sort - | uniq -ui |tr -d '\n')

我了解 sed 的作用,并且 at 的部分sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1./i'基本上是取出与用户名示例 SOMETHING_USERNAME 等效的正则表达式。

find . -iname '*.txt'- 查找扩展名为 txt 的文件的名称?之所以iname使用它是因为它应该忽略大小写?

sort -如果有多个文件,是否按顺序对文件进行排序?

uniq -ui允许仅存储唯一的用户名。

tr -d删除其余的?

我想看看这里的理解是否正确,如果不正确,它是如何工作的。

添加代码以获得进一步的帮助和对我自己的更多理解。

function process_zip {
    file="$1" #file is set to the INPUT
    folder="$file-$(date +%s)" #Setting Foldername

    declare -x   folder=${file%.*}     # Adding the file name to the left of the date and seconds.
    echo "filename to process" $file #printing filename


    echo "folderName" $folder #printing folder name
    mv "input/$file" in_progress #Move the folder from input to in_progress
    cd in_progress; #Go to progress

    # check file for validity before unzipping


    unzip -qq $file -d $folder; #not sure what -qq does exactly. This command unzips and checks if folder is available?
    echo "unzip completed" #prints
    cd $folder/placeholder/placeholder2; #goes into that folder?
    chmod -R 770 ** #Run recursively? understand this little but need more help.
    rsync -r * /placeholder1/placeholder2/placeholder3/placeholder4/; 
    echo "copy completed"
    #I want to use this next line so that the cut isn't hardcoded and works for files longer than 10 characters.
    #extract=$(find . -iname '*.txt' | sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1,/i' | sort - | uniq -ui | tr -d '\n')
    extract=$(cut -c -10 <<<"$file")
    echo "Extracted part is"$extract
    java -jar /placeholder1/placeholder2/placeholder3/placeholder4/placeholder5.jar $extract &
    cd ../../..; #back to in_progress
    pwd
    mv $file ../completed
    rm -r $folder &
    cd ../;
    echo "finished processing" $file
}

remaining=$(ls -1 input | grep .zip | wc -l) #It checks for more input files?

echo "${remaining} files to process"


while [ $remaining -gt 0 ]
do
    file=$(ls -t1 input| grep .zip | head -n1)
    echo "$file"
    process_zip "$file";

    remaining=$(ls -1 input | grep .zip | wc -l)
    echo "${remaining} files to process"
done;


find completed/* -mtime +15 -exec rm {} \;
find errors/* -mtime +15 -exec rm {} \;
find logs/* -mtime +15 -exec rm {} \;

echo "all done"

谢谢你!

答案1

你说的非常正确。下面是我的看法。

find . -iname '*.txt'查找扩展名为 的文件的名称txt,忽略大小写(因此 ./wibble/wobble/wubble.Txt 可能是一个示例)

sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1./i'查找最后一个下划线序列,后跟 4 个数字,后跟下划线,可选地后跟文件路径中的一系列字母、数字、竖线以及可能的其他字符。如果它找到这样的序列,它会丢弃所有其他内容,丢弃前导_并附加一个.字符,否则它会保持文件名不变。

sort -对文件名进行排序,尊重大小写(尽管区域设置排序算法可能在第一个实例中忽略大小写)。

uniq -ui拒绝出现多次的名称,忽略大小写差异。

tr -d '\n'通过删除换行符将所有文件名连接在一起。

这段代码看起来很脆弱!它可能期望有一个名为类似的文件sub/dir/pics_2023_happyxmas!/company/party/photos.txt并想要提取2023_happyxmas..添加另一个带有 txt 扩展名的文件可能会为结果变量提供另一个组件username,尽管您可以使用.字符将它们分开。

允许匹配哪些字符可能取决于locale运行脚本的环境。

添加扩展名为 的另一个文件,txt但名称中不含下划线,将破坏使用.拆分名称的功能。

如果程序在受控环境中运行,那可能没问题,但我肯定会拒绝sed它发现的任何与预期模式不匹配的行,而不是将它们原封不动地传递。

相关内容