명령줄에서 파일 목록을 수락하고 xargs를 사용하여 모든 파일의 날짜가 지정된 복사본(basename_date.extension)을 생성하려면 어떻게 해야 합니까?

명령줄에서 파일 목록을 수락하고 xargs를 사용하여 모든 파일의 날짜가 지정된 복사본(basename_date.extension)을 생성하려면 어떻게 해야 합니까?

이 문제를 해결하기 위해 많은 시간을 보냈습니다여기xargs 호출에 의존하지 않고 올바른 출력을 얻을 수 있었습니다 bash(이 튜토리얼에서는 다루지 않음). 하위 호출에서 bash올바른 참조를 얻는 데 시간이 걸렸습니다 . 어떤 이유로 변수에 xargs저장 하고 다시 계산하여 새 변수에 저장해야 했습니다.replace-strdate

편집: 나는 이것이 rename이 문제를 해결하는 데에도 사용될 수 있다는 것을 알고 있지만 이것은 내가 링크한 튜토리얼에서 아직 다루지 않았으며 이 연습의 초점도 아닙니다(언급한 대로 xargs 사용).

  • 분명히 매개변수 확장은 = {}에서 작동하지 않으므로 replace-str"{}%%.*"를 수행하고 파일 확장자를 가져올 수 없습니다.
  • 분명히 명령에서 실행되는 하위 bash 프로세스 내에서 사용되는 경우 큰따옴표로 묶인 변수도 todaynull이 됩니다 xargs.

    # %<conversions> come from 'man 3 strftime'                                                                                                                  
    today=$( date "+%Y-%m-%d" )

    # make prefix date copy                                                                                                                                      
    #ls "$@" | xargs -I ^ cp ^ "${today}_^"                                                                                                                        

    #make suffix date copy                                                                                                                                                                                                                                                       
    echo "$@" | sed "s; ;\n;g" | xargs -I {} \
                          bash -cs 'var="{}"; td=$( date "+%Y-%m-%d" ); \
                                    echo "${var%%.*}_${td}.${var##*.}"'
    #prints basename_.bash i.e. without date
    echo "$@" | sed "s; ;\n;g" | xargs -I {} \
                          bash -cs 'var="{}"; \
                                    echo "${var%%.*}_${today}.${var##*.}"'

출력됩니다

    s1_2021-03-11.bash s2_2021-03-11.bash 

입력할 때

    ./myscript s1.bash s2.bash

편집: 입력을 반복하려면 다음과 같습니다.

    ./myscript file1.ext file2.ext file3.ext ... fileN.ext

실행 후 ls다음 파일이 존재해야 합니다.

    file1_yyyy-mm-dd.ext ... fileN_yyyy-mm-dd.ext

가능하다면 웹사이트의 튜토리얼에서 아직 이 내용을 다루지 않았기 때문에 작동하지 않는 솔루션을 찾고 싶습니다 bash -c. 그래서 그것이 문제를 해결하려는 의도인지 의심스럽습니다. 또한 매개변수 확장이 xargs와 작동하지 않고 다른 날짜 변수가 필요하다는 혼란을 이해하고 싶습니다.

답변1

xargs/sed의 GNU 버전에 액세스할 수 없는 경우 xargs-safe 파일 이름을 인용해야 합니다.

용법:

 ./myscript   your list of files goes here
#!/bin/bash

# user defined function: qXargs
# backslashes all chars special to xargs:
# SPC/TAB/NL/double quotes, single quotes, and backslash.

qXargs() {
  printf '%s\n' "$1" |
  sed \
    -e "s:[\\'${IFS%?}\"]:\\\\&:g" \
    -e '$!s:$:\\:'  \
  ;
}

# loop over command-line arguments
# quote them to make xargs safe and
# break apart arg into head portion and
#'extension and slip in today's date

today=$(date +'%Y-%d-%m')

for arg
do
   src=$(qXargs "$arg")
  head=$(qXargs "${arg%.*}")
  tail=$(qXargs "${arg##*.}")
  printf '%s\n%s_%s.%s\n'  \
    "$src" \
    "$head" "$today" "$tail" ;
done | xargs -n 2 -t mv -f --

유틸리티는 GNU 버전이라고 가정합니다.

#!/bin/bash
### this is the ./myscript file
d=$(date +'%Y-%d-%m')
printf '%s\0' "$@" |
sed -Ez "p;s/(.*)(\..*)/\1$d\2/" |
xargs -r0 -n2 -t mv -f --

노트:

  • xargs 대체 문자열 {}에서 확장을 가져올 수 없다는 것에 대한 혼란은 bcoz {}가 xargs에게 인수로 바꾸도록 상기시키는 자리 표시자일 뿐이라는 것입니다. 따라서 xargs 명령을 구문 분석할 때 쉘은 이를 볼 수 없습니다.

관련 정보