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예상 패턴과 일치하지 않는 줄을 발견하면 그대로 전달하는 대신 거부할 것입니다.

관련 정보