如果成功則透過管道傳輸命令的輸出

如果成功則透過管道傳輸命令的輸出
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`

我想head -1僅當第一個命令成功時才執行第二個命令()。如何改進這個指令?

答案1

嘗試這個:

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`

傳遞xargs-r標誌將導致它僅basename在從標準輸入 ( ) 讀取至少一項時運行head -1

head -1將運行,但您不會看到或捕獲它的任何輸出。

另外,如果您不希望使用者看到 的任何錯誤輸出ls,您可以將ls的 stderr 流重新導向到/dev/null

INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`

另請注意,我在 周圍添加了引號$MY_DIR。這樣,如果$MY_DIR包含空格,則該指令就不會失敗。

如果您使用的是現代 shell(例如 bash),則應該使用$( )捕獲 shell 而不是反引號。您還應該考慮更改變數的樣式。通常應該避免在腳本中使用全大寫的變數名稱。此樣式通常保留用於保留變數和環境變數。

input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)

答案2

在管道中,所有命令都是同時啟動和運行的,而不是一個接一個地運行。所以你需要將輸出儲存在某個地方。

if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
  first_file=$(printf '%s\n' "$ls_output" | head -n 1)
  first_file_name=$(basename -- "$first_file")
fi

請注意,它假設檔案名稱不包含換行符。使用xargs也意味著空白字元、單引號和雙引號以及反斜線的問題。不加引號的變數將意味著空格、製表符和通配符的問題。忘記--意味著以-.

要取得最舊檔案的基本名稱,而zsh沒有任何字元限制(也避免了命令參數大小有限的問題):

 first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))

如果沒有匹配,該命令將失敗併中止腳本。您也可以這樣做:

 first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))

在這種情況下,first_file_name如果符合則陣列將包含 1 個元素,如果不符合則包含 0。然後你可以這樣做:

 if (($#first_file_name)); then
    printf 'Match: %s\n' $first_file_name
 else
    echo >&2 No match
 fi

答案3

在目錄中尋找最新修改的文​​件:

latest() {
  local file path=${1:-.} ext=${2-} latest
  for file in "${path%/}"/*"$ext"; do 
    [[ $file -nt $latest ]] && latest=$file
  done
  [[ $latest ]] && printf '%s\n' "$latest"
}

用法:latest [directory/path/ [.extension]]

basename使用參數擴展而不是調用。

in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}

在包含以下內容的目錄中:

foo.xml bar.xml baz.xml newest.xml

base_fn 變數的內容為:newest

為了正確使用它來滿足您的請求的目的:

check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
  base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
  printf '%s\n' "No file found in $check_dir" >&2
fi

編輯:在審查問題後,我意識到ls有問題的命令正在尋找最老的目錄中的檔案。這個相同的函數可以重新命名為oldestand has[[ $file -ot $oldest ]] && oldest=$file來實現相同的效果。對於任何混亂,我們深表歉意。

需要注意的重要一點是,在人類的任何情況下,您絕對不應該解析 ls 的輸出。絕不。

答案4

我認為這裡最好的選擇是:

ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
      INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
      echo "Error!"
fi

如果沒有文件,則 ls 的回傳碼為 2,但如果找到某個文件,則回傳碼為 0。

相關內容