Bash

如何編輯名稱包含空格的生成文件列表

  • July 20, 2020

我有一個相對較小的文件名列表,這些文件名是從基於find. 文件名包含空格和可能的標點符號,但絕對沒有其他非列印字元或換行符。

例如,

Netherlands/Purge (GDPR) 2020-01-09.txt
Netherlands/Purge (GDPR) 2020-01-27.txt
Switzerland/New mailing 2020-01-27.txt

我想將這些文件作為一組(vi file1 file2 file3而不是vi file1; vi file2; vi file3)編輯,部分是為了讓我可以輕鬆地在它們之間前後跳轉。

我從使用生成的文件名列表作為參數列表開始——使用空格,它有一個標準的find -print0 | xargs -0 mycommand解決方案。mycommand不幸的是,當是編輯器時這不起作用,因為雖然xargs可以組裝要編輯的文件集,但標準輸入已經從管道中佔用,我看不到就地執行編輯器的方法。我不能使用find -exec vi {} +,因為我正在使用管道來驗證文件名集,而不僅僅是find它本身。

我的另一個選擇是複制和粘貼,組合文件名列表,用引號將它們括起來,然後在結果前面加上vi. 對於這三個文件來說,這是微不足道的,但在一般情況下,它不是一個易於重用的解決方案,

vi 'Netherlands/Purge (GDPR) 2020-01-09.txt' 'Netherlands/Purge (GDPR) 2020-01-27.txt' 'Switzerland/New mailing 2020-01-27.txt'

給定一個 GNU/Linux 平台bash作為我的首選 shell(以防萬一),我如何編輯類似生成的文件列表?

既然你在 Bash,

#!/bin/bash
readarray -d '' -t files < <(find path -type f -print0)
vi -- "${files[@]}"

替換find path -type f -print0為您的實際管道。

儘管您的文件沒有換行符,但使用者glenn jackman添加了對此類文件名的支持。

要為 使用製表符而不是緩衝區vi,請添加-p標誌:vi -p ...


如果不需要管道,您可以直接使用該-exec選項:

find path -type f -exec vi -- {} +

不幸的是,當 mycommand 是編輯器時,這不起作用,因為雖然 xargs 可以組裝要編輯的文件集,但標準輸入已經從管道中佔用,我看不到就地執行編輯器的方法。

這種方式記錄在 GNU Findutils 的手冊頁中xargs

  -o, --open-tty
         Reopen stdin as /dev/tty in the child process  before  executing
         the  command.  This is useful if you want xargs to run an inter‐
         active application.

這樣你就可以使用

find . -name 'pattern' -print0 | xargs -0o vim

但是,它是一個較新的功能。我在具有 xargs 4.4.2 的舊系統中看不到它;我在具有 xargs 4.7.0 的 Ubuntu 18 上看到它。

現在xargs可能十年前沒有這個-o選項,但是 Bash 程序替換在十年前就已經存在,並且xargs可以-a選擇從文件而不是標準輸入中讀取。

所以這個問題可以不用xargs -o這樣解決:

xargs -0 -a <(find . -name 'pattern' -print0) vim

因為xargs正在讀取(它認為是)作為參數接收的文件,所以它單獨留下了標準輸入。

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