bash for 루프에서 명령 대체 사용

bash for 루프에서 명령 대체 사용

뻔한 실수를 했을 수도 있지만, 강력한 팁을 사용할 수 있었습니다 :-)

for file in *; do ls $file | var=$(ls $file | grep -Eo '.{18}$' | cut -d '.' -f1 |sed 's/.\{12\}/&./'); echo "var is $var. File is $file";done

결과: $var가 비어 있습니다. $file은 그렇지 않습니다.$var가 비어 있는 이유는 무엇입니까?

테스트 문자열을 $file에 수동으로 넣고 다음과 같이 실행하면 $var에 내가 원하는 내용이 포함됩니다.

var=$(ls $file | grep -Eo '.{18}$' | cut -d '.' -f1 |sed 's/.\{12\}/&./')

그래서 이 문제를 일으키는 for 루프에 관한 뭔가가 있습니다. $var 변수에는 다음 명령문에서 사용할 수 없도록 하는 범위 제한이 있는 것 같습니다.

행복한 부활절 보내세요 :-)

완전한 예:

질문에 따르면 여기에 내 의심을 명확하게 해주는 예가 있습니다. 파일 날짜는 inventory_a_test-20190605161153.txt1파일 이름의 날짜와 일치해야 합니다. 먼저 파일을 잘못된 날짜로 설정했습니다.

$ touch inventory_a_test-20190605161153.txt
$ ls -l --full-time inventory_a_test-20190605161153.txt
-rw-rw-r-- 1 root root 0 **2021-04-05** 15:02:05.000000000 +0200 inventory_a_test-20190605161153.txt

이제 날짜를 수정하기 위해 bash의 for 루프로 아래와 같은 명령 흐름을 작성하고 싶습니다.

$ file=inventory_a_test-20190605161153.txt
$ ls $file | grep -Eo '.{18}$' | cut -d '.' -f1 |sed 's/.\{12\}/&./'
201906051611.53
$ touch -a -m -t 201906051611.53 $file
$ ls -l --full-time inventory_a_test-20190605161153.txt
-rw-rw-r-- 1 root root 0 **2019-06-05** 16:11:53.000000000 +0200   inventory_a_test-20190605161153.txt

답변1

이 부분은 말이 안 돼요:

ls $file | $(something)

$(command)형식은 "실행 command및 출력을 변수로 처리"를 의미합니다. 이는 파이프 입력을 받아들일 수 있는 것이 아닙니다. 내가 뭘 그리워하니?의미는쓰여진 내용은 다음과 같습니다.

for file in *; do 
    var=$(ls "$file" | grep -Eo '.{18}$' | cut -d '.' -f1 |sed 's/.\{12\}/&./'); 
    echo "var is $var. File is $file"
done

그러나 이상한 파일 이름으로 인해 이는 비참하게 실패합니다.실제로 출력을 구문 분석하고 싶지는 않습니다.ls. 게다가 ls여기서는 전혀 필요하지 않습니다! 당신은가지다파일 이름이 ls더 복잡해지고 오류가 발생할 수 있습니다. 이렇게 하면 원하는 작업이 수행됩니다.

for file in *; do
    timestamp=$(sed -E 's/.*(.{12})(..)\.[^.]*$/\1.\2/' <<<"$file")
    touch -a -m -t "$timestamp" -- "$file"
done

sed파일의 최종 확장자 앞의 마지막 14자만 인쇄 합니다 ( 파일 이름 끝까지 일치 한 다음 0 이상과 \.[^.]*$/일치함 ). 그러나 마지막 2자를 처음 12자에서 분리하여 효과적으로 생성합니다. 당신의 타임스탬프....

답변2

@terdon 아니요, 친절한 솔루션에 감사드립니다. 다른 Linux 초보자용. 또한 일부 시간대 문제가 발생하여 최종 결과는 다음과 같습니다.

for file in *; do
     timestamp=$(sed -E 's/.*(.{12})(..)\.[^.]*$/\1.\2/') <<<"$file"
     TZ=UTC-2 touch -a -m -t "$timestamp" -- "$file"
done

추신: 저는 이 웹사이트를 사용하여 정규식을 분석합니다.https://regex101.com/

관련 정보