Bash

如何在命令行上接受文件列表並使用 xargs 創建所有文件的日期副本(basename_date.extension)?

  • March 13, 2021

從這裡開始,我已經花了很多時間來解決這個問題,並且我已經設法在不依賴 xargs 呼叫的情況下獲得正確的輸出bash(本教程沒有涵蓋)。需要一段時間才能在其中的子bash呼叫中正確引用xargs,由於某種原因,我不得不將其保存replace-str在一個變數中,並重新計算date並將其保存在一個新變數中,因為:

編輯:我知道這rename也可以用來解決這個問題,但是我連結的教程中還沒有涉及到,而不是這個練習的重點(如前所述,它是使用 xargs)

  • 顯然參數擴展不適用於replace-str= {} 所以我不能做 “{}%%.*” 並獲取文件副檔名
  • 顯然,如果在命令中執行的子 bash 程序中使用,即使是雙引號變數 ,today也會為空。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 以及需要另一個日期變數的困惑。

如果我們無法訪問 xargs/sed 的 GNU 版本,那麼我們需要負責引用對 xargs 安全的文件名。

用法:

./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 用參數替換它的佔位符。所以shell在解析xargs命令時看不到它。

引用自:https://unix.stackexchange.com/questions/638864