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'改行文字を削除して、すべてのファイル名を1つに連結します。

このコードは脆弱に見えます!同じ名前のファイルがあると予想してsub/dir/pics_2023_happyxmas!/company/party/photos.txttxt2023_happyxmas.拡張子を持つ別のファイルを追加すると、結果変数に異なるコンポーネントが提供される可能性がありますusername。ただし、.文字を使用して区別することはできます。

一致が許可される文字は、localeスクリプトが実行される環境によって異なります。

txt名前にアンダースコアのない拡張子を持つ別のファイルを追加すると、.パーティション名を使用する機能が中断されます。

プログラムが制御された環境で実行されている場合は問題ありませんが、sed予想されるパターンと一致しない行が見つかった場合は、そのまま渡すのではなく拒否します。

関連情報