find -exec 具有多个命令

发布于 2024-10-19 06:08:41 字数 188 浏览 5 评论 0原文

我尝试将 find -exec 与多个命令一起使用,但没有成功。有谁知道以下命令是否可行?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

基本上,我试图打印当前目录中每个 txt 文件的最后一行,并在行末尾打印一个逗号,后跟文件名。

I am trying to use find -exec with multiple commands without any success. Does anybody know if commands such as the following are possible?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

Basically, I am trying to print the last line of each txt file in the current directory and print at the end of the line, a comma followed by the filename.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

非要怀念 2024-10-26 06:08:41

find 接受命令的多个 -exec 部分。例如:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

请注意,在这种情况下,只有第一个命令成功返回时,第二个命令才会运行,正如 @Caleb 提到的。如果您希望这两个命令无论成功或失败都运行,您可以使用以下构造:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;

find accepts multiple -exec portions to the command. For example:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

Note that in this case the second command will only run if the first one returns successfully, as mentioned by @Caleb. If you want both commands to run regardless of their success or failure, you could use this construct:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;
咋地 2024-10-26 06:08:41
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;
归途 2024-10-26 06:08:41

以下之一:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;

One of the following:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;
情域 2024-10-26 06:08:41

另一种方法是这样的:

multiple_cmd() { 
    tail -n1 "$1" 
    ls "$1"
}
export -f multiple_cmd
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

在一行中

multiple_cmd() { tail -1 "$1"; ls "$1"; }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • multiple_cmd()” - 是一个函数
  • export -f multiple_cmd” - 将导出它,以便任何其他子 shell 都可以看到它
  • find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - find 将在您的示例中执行该函数

这样, multiple_cmd 可以像这样一样长和复杂,你需要。

Another way is like this:

multiple_cmd() { 
    tail -n1 "$1" 
    ls "$1"
}
export -f multiple_cmd
find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;

in one line

multiple_cmd() { tail -1 "$1"; ls "$1"; }; export -f multiple_cmd; find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;
  • "multiple_cmd()" - is a function
  • "export -f multiple_cmd" - will export it so any other subshell can see it
  • "find *.txt -exec bash -c 'multiple_cmd "$0"' {} \;" - find that will execute the function on your example

In this way multiple_cmd can be as long and as complex, as you need.

栖迟 2024-10-26 06:08:41

有一个更简单的方法:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

或者:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"

There's an easier way:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";
done

Alternatively:

while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"
我也只是我 2024-10-26 06:08:41

扩展@Tinker的答案,

就我而言,我需要创建一个命令 |命令 | -exec 中的命令 打印文件名以及在包含特定文本的文件中找到的文本。

我能够做到这一点:

find . -name config -type f \( -exec  grep "bitbucket" {} \; -a -exec echo {} \;  \) 

结果是:

    url = [email protected]:a/a.git
./a/.git/config
    url = [email protected]:b/b.git
./b/.git/config
    url = [email protected]:c/c.git
./c/.git/config

Extending @Tinker's answer,

In my case, I needed to make a command | command | command inside the -exec to print both the filename and the found text in files containing a certain text.

I was able to do it with:

find . -name config -type f \( -exec  grep "bitbucket" {} \; -a -exec echo {} \;  \) 

the result is:

    url = [email protected]:a/a.git
./a/.git/config
    url = [email protected]:b/b.git
./b/.git/config
    url = [email protected]:c/c.git
./c/.git/config
静谧幽蓝 2024-10-26 06:08:41

我不知道是否可以使用 find 来完成此操作,但替代解决方案是创建一个 shell 脚本并使用 find 来运行它。

lastline.sh:

echo "$(tail -1 "$1"),$1"

使脚本可执行

chmod +x lastline.sh

使用find

find . -name "*.txt" -exec ./lastline.sh {} \;

I don't know if you can do this with find, but an alternate solution would be to create a shell script and to run this with find.

lastline.sh:

echo "$(tail -1 "$1"),$1"

Make the script executable

chmod +x lastline.sh

Use find:

find . -name "*.txt" -exec ./lastline.sh {} \;
何以畏孤独 2024-10-26 06:08:41

感谢卡米洛·马丁(Camilo Martin),我能够回答一个相关问题:

我想做的是

find ... -exec zcat {} | wc -l \;

不起作用。不过,

find ... | while IFS= read -r file; do echo "$file: $(zcat "$file" | wc -l)"; done

确实有效,所以谢谢!

Thanks to Camilo Martin, I was able to answer a related question:

What I wanted to do was

find ... -exec zcat {} | wc -l \;

which didn't work. However,

find ... | while IFS= read -r file; do echo "$file: $(zcat "$file" | wc -l)"; done

does work, so thank you!

写下不归期 2024-10-26 06:08:41

丹尼斯的第一个回答是解决问题的答案。但事实上,它不再是像标题所暗示的那样,在一个 -exec 中使用多个命令进行 find 。要回答一个带有多个命令的 -exec 问题,我们必须寻找其他东西来解决。以下是一个示例:

使用多个 {} 引用使用一个 -exec 命令保留过去 7 天内修改的最后 10000 行 .log 文件

  1. See该命令将对哪些文件执行什么操作:

    find / -name "*.log" \
        -类型 f -mtime -7 \
        -exec sh -c '
            echo tail -10000“$1”>>虚构;回声猫fictmp \> “$1”' _ {} \;
    
  2. 执行(注意不再有 \>,但这次只有 >):

    find / -name "*.log" \
        -类型 f -mtime -7 \
        -exec sh -c '
            尾部 -10000 "$1" >虚构;猫小说> “1美元”; rm fictmp"' _ {} \;
    

The first answer of Denis is the answer to resolve the trouble. But in fact it is no more a find with several commands in only one -exec like the title suggests. To answer the one -exec with several commands thing we will have to look for something else to resolve. Here is a example:

Keep last 10000 lines of .log files which has been modified in the last 7 days using one -exec command using several {} references

  1. See what the command will do on which files:

    find / -name "*.log" \
        -type f -mtime -7 \
        -exec sh -c '
            echo tail -10000 "$1" \> fictmp; echo cat fictmp \> "$1"' _ {} \;
    
  2. Do it (note no more \> but only >this time):

    find / -name "*.log" \
        -type f -mtime -7 \
        -exec sh -c '
            tail -10000 "$1" > fictmp; cat fictmp > "$1" ; rm fictmp"' _ {} \;
    
∝单色的世界 2024-10-26 06:08:41

我通常将 find 嵌入到一个小的 for 循环中,其中 find 在带有 $() 的子命令中执行。

那么您的命令将如下所示:

for f in $(find *.txt); do echo "$(tail -1 $f), $(ls $f)"; done

好处是您只需使用 $f 而不是 {} 而不是 -exec …您将所有命令写在 do之间;完成

不确定你真正想做什么,但也许是这样的?

for f in $(find *.txt); do echo $f; tail -1 $f; ls -l $f; echo; done

I usually embed the find in a small for loop one liner, where the find is executed in a subcommand with $().

Your command would look like this then:

for f in $(find *.txt); do echo "$(tail -1 $f), $(ls $f)"; done

The good thing is that instead of {} you just use $f and instead of the -exec … you write all your commands between do and ; done.

Not sure what you actually want to do, but maybe something like this?

for f in $(find *.txt); do echo $f; tail -1 $f; ls -l $f; echo; done
挽清梦 2024-10-26 06:08:41

我找到了这个解决方案(也许它已经在评论中说过,但我找不到任何答案)

您可以使用“bash -c”连续执行多个命令,

find . <SOMETHING> -exec bash -c "EXECUTE 1 && EXECUTE 2 ; EXECUTE 3" \;

在您的情况下

find . -name "*.txt" -exec bash -c "tail -1 '{}' && ls '{}'" \;

我用测试文件测试了它:

 [gek@tuffoserver tmp]$ ls *.txt


casualfile.txt
[gek@tuffoserver tmp]$ find . -name "*.txt" -exec bash -c "tail -1 '{}' && ls '{}'" \;
testonline1=some TEXT
./casualfile.txt

I found this solution (maybe it is already said in a comment, but I could not find any answer with this)

you can execute MULTIPLE COMMANDS in a row using "bash -c"

find . <SOMETHING> -exec bash -c "EXECUTE 1 && EXECUTE 2 ; EXECUTE 3" \;

in your case

find . -name "*.txt" -exec bash -c "tail -1 '{}' && ls '{}'" \;

i tested it with a test file:

 [gek@tuffoserver tmp]$ ls *.txt


casualfile.txt
[gek@tuffoserver tmp]$ find . -name "*.txt" -exec bash -c "tail -1 '{}' && ls '{}'" \;
testonline1=some TEXT
./casualfile.txt
清泪尽 2024-10-26 06:08:41

find+xargs 答案。

下面的示例查找所有 .html 文件并创建一个附加了 .BAK 扩展名的副本(例如 1.html > 1 .html.BAK)。

具有多个占位符的单个命令 具有

find . -iname "*.html" -print0 | xargs -0 -I {} cp -- "{}" "{}.BAK"

多个占位符的多个命令

find . -iname "*.html" -print0 | xargs -0 -I {} echo "cp -- {} {}.BAK ; echo {} >> /tmp/log.txt" | sh

# if you need to do anything bash-specific then pipe to bash instead of sh

由于参数引用和 --,此命令还可以处理以连字符开头或包含空格(例如 -my file.html)的文件cp 之后,向 cp 发出参数结束和实际文件名开始的信号。

-print0 使用空字节终止符对结果进行管道传输。


对于 xargs-I {} 参数将 {} 定义为占位符;您可以使用任何您喜欢的占位符; -0 表示输入项以 null 分隔。

A find+xargs answer.

The example below finds all .html files and creates a copy with the .BAK extension appended (e.g. 1.html > 1.html.BAK).

Single command with multiple placeholders

find . -iname "*.html" -print0 | xargs -0 -I {} cp -- "{}" "{}.BAK"

Multiple commands with multiple placeholders

find . -iname "*.html" -print0 | xargs -0 -I {} echo "cp -- {} {}.BAK ; echo {} >> /tmp/log.txt" | sh

# if you need to do anything bash-specific then pipe to bash instead of sh

This command will also work with files that start with a hyphen or contain spaces such as -my file.html thanks to parameter quoting and the -- after cp which signals to cp the end of parameters and the beginning of the actual file names.

-print0 pipes the results with null-byte terminators.


for xargs the -I {} parameter defines {} as the placeholder; you can use whichever placeholder you like; -0 indicates that input items are null-separated.

-柠檬树下少年和吉他 2024-10-26 06:08:41

应该使用 xargs :)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

另一个(在 osx 上工作)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'

should use xargs :)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

another one (working on osx)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'
背叛残局 2024-10-26 06:08:41

这是我的 bash 脚本,您可以使用它来查找多个文件,然后使用命令处理所有文件。

使用示例。此命令将 file linux 命令应用于每个找到的文件:

./finder.sh file fb2 txt

Finder 脚本:

# Find files and process them using an external command.
# Usage:
#   ./finder.sh ./processing_script.sh txt fb2 fb2.zip doc docx

counter=0
find_results=()
for ext in "${@:2}"
do
    # @see https://stackoverflow.com/a/54561526/10452175
    readarray -d '' ext_results < <(find . -type f -name "*.${ext}" -print0)

    for file in "${ext_results[@]}"
    do
        counter=$((counter+1))
        find_results+=("${file}")
        echo ${counter}") ${file}"
    done
done
countOfResults=$((counter))
echo -e "Found ${countOfResults} files.\n"


echo "Processing..."
counter=0
for file in "${find_results[@]}"
do
    counter=$((counter+1))
    echo -n ${counter}"/${countOfResults}) "
    eval "$1 '${file}'"
done
echo "All files have been processed."

Here is my bash script that you can use to find multiple files and then process them all using a command.

Example of usage. This command applies a file linux command to each found file:

./finder.sh file fb2 txt

Finder script:

# Find files and process them using an external command.
# Usage:
#   ./finder.sh ./processing_script.sh txt fb2 fb2.zip doc docx

counter=0
find_results=()
for ext in "${@:2}"
do
    # @see https://stackoverflow.com/a/54561526/10452175
    readarray -d '' ext_results < <(find . -type f -name "*.${ext}" -print0)

    for file in "${ext_results[@]}"
    do
        counter=$((counter+1))
        find_results+=("${file}")
        echo ${counter}") ${file}"
    done
done
countOfResults=$((counter))
echo -e "Found ${countOfResults} files.\n"


echo "Processing..."
counter=0
for file in "${find_results[@]}"
do
    counter=$((counter+1))
    echo -n ${counter}"/${countOfResults}) "
    eval "$1 '${file}'"
done
echo "All files have been processed."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文