我在各种不同的子目录中有数百个文件。其中一些具有正确的文件扩展名,但其中一些没有。我想重命名所有没有文件扩展名的文件,并在其文件名后附加 .mp4 扩展名。其他文件应该保持不变。如何使用 Bash 自动执行此重命名操作?或者我需要像 Perl 或 Python 这样的真正的脚本语言吗?
我试图在我的.bashrc文件中定义以下 bash 函数:
function myfind() {
find $1 -not -path venv -not -path .tox -name "$2" | xargs grep -n "$3"
}
Run Code Online (Sandbox Code Playgroud)
这没有达到我的预期。当我使用该函数搜索文件中的文本时,例如
myfind . *.py test
Run Code Online (Sandbox Code Playgroud)
它不返回任何内容。但是当我直接使用表达式时,即
find . -not -path venv -not -path .tox -name "*.py" | xargs grep -n "test"
Run Code Online (Sandbox Code Playgroud)
它返回一些匹配项。
我已经尝试使用双引号,例如
function myfind() {
find $1 -not -path venv -not -path .tox -name '"$2"' | xargs grep -n '"$3"'
}
Run Code Online (Sandbox Code Playgroud)
或者
function myfind() {
find $1 -not -path venv -not -path .tox -name "'$2'" …Run Code Online (Sandbox Code Playgroud) 我想制作一个脚本来浏览我的整个树并删除所有隐藏文件(例如“.git”),除了一些(例如“.@__thumb”)。我制作了一个脚本来浏览我的树并删除所有以“.”开头的文件。
这里是:
find . -depth -type d -name '.*' |
while read f
do
dn=`dirname "$f"`
bn=`basename "$f"`
mv "$dn/$bn" "$dn/${bn//.}"
done
Run Code Online (Sandbox Code Playgroud)
然后我想调整它并添加一个条件,以便当我的文件夹/文件被称为“.@__thumb”时(这是一个我不想删除的文件夹)它不会删除“.@__thumb”。
我懂了:
thumb=".@__thumb"
echo $thumb
find . -depth -type d -name '.*' |
while read f
do
if [[ $bn != $thumb ]]
then
dn=`dirname "$f"`
bn=`basename "$f"`
mv "$dn/$bn" "$dn/${bn//.}"
fi
done
Run Code Online (Sandbox Code Playgroud)
然而,我的条件似乎没有用。我的脚本仍然会删除我的“.@__thumb”文件夹。你知道问题可能来自哪里或任何改进的想法吗?我不知道我的解释是否清楚。如果您有任何疑问,请不要犹豫。非常感谢。
这是我的查找命令:
find -mtime -$a | xargs zgrep -il ''$b'' | xargs zgrep -il ''$c'' | xargs zgrep -il ''$d'' | xargs zgrep -il 'ST.997' | sort -u
Run Code Online (Sandbox Code Playgroud)
这是上述命令的示例输出:
example_file.dat.Z
example2_file.dat.Z
example2_file.dat.bak.1234567890.Z
example3_file.dat.Z
example3_file.dat.bak.Z
example4_file.dat.Z
example4_file.dat.bak.qwertyuiop.Z
Run Code Online (Sandbox Code Playgroud)
如您所见,它输出带有“.bak”扩展名的相同文件。我想要的是在运行脚本时排除/不显示该文件。像这个示例输出:
example_file.dat.Z
example2_file.dat.Z
example3_file.dat.Z
example4_file.dat.Z
Run Code Online (Sandbox Code Playgroud)
编辑:我忘了。有时它是在 zip 文件中。
在 linux 中,文件名“斜杠”和“空字符”中只禁止使用两个字符。因此,每种脚本语言中的每个具有特殊含义的字符都应该转义,但文件名中也允许每个转义序列!更糟糕的是 ie bash 一些转义方法只能转义一些字符,因此要转义大量不同的字符,您应该一起使用几种不同的转义方法,但它们会相互干扰!更糟糕的是,某些命令使用某些字符来达到目的,而其他命令使用其他字符,因此对于文件的每一个简单操作,您都应该以不同的方式转义文件名!更糟糕的是,只能使用空字符来安全地分隔文件名,但大多数命令无法使用它。更糟糕的是,在 linux 中基本上一切都是文件......
所以告诉我我错在哪里......甚至有可能正确处理所有可能的文件名吗?
澄清。本来我想:
列出给定路径下的文件和文件夹
搜索列表以查找与给定条件(年龄或文件模式或大小)匹配的文件
我不能使用任何特殊字符来转义文件名,因为我不知道文件名中可能包含什么字符。经过一些测试,我发现任何字符出现都是时间问题。
我已经尝试过定义过滤器,例如:
audio_ext=(*.mp3 *.wav *.ogg *.mid *.mod *.stm *.s3m *.it *.wma *.669 *.ac3)
很快我意识到这种方式我无法为多种用途定义过滤器,因为通配符会踢掉rigths。所以我禁用了 globbing 和 history by set -fH。在没有通配符的情况下,我必须手动进行扩展
while IFS= read -r -d $'\0'; do
list+=("$REPLY")
done < <( find . -maxdepth 1 -mindepth 1 ${params[@]} -print0 2>/dev/null )
params数组"-iname" "*.mp3" "-o" "-iname" "*.wav"等在哪里。这一直有效,直到文件名称中有“(”。查找有关错误用法的返回错误。
说实话......直到最近 15 年来,我一直使用批处理脚本来完成这项任务。花在写作上的时间大约是一两个下午。它有缺点和!文件名问题,但通常它有效。现在我已经尝试了将近两个月的时间来用 bash 编写它。它丑陋、复杂、漏洞百出,而且似乎永远不会奏效。
有谁知道为什么在 grep 命令中使用两个 * 不会返回任何内容。我原来的命令如下:
find | grep 0000\:00\:*.0/usb1/authorized_default
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我试图返回一个我不知道 PCI 文件夹名称的文件。此命令按预期完美运行(将 * 作为通配符)并确定 usb1 位于“1a”文件夹中。
如果我在命令中放置另一个通配符以将 'usb1' 替换为 'usb*',为什么 grep 不返回任何结果?我的最终目标是返回所有的authorized_default 文件,我意识到可以通过其他方式并且可能更有效地完成这些文件。然后我的问题就不是我该怎么做,但是当我将另一个“*”符号放入等式时,为什么 grep 不返回结果?
find | grep 0000\:00\:*.0/usb*/authorized_default
Run Code Online (Sandbox Code Playgroud)
提前感谢您的时间和回复。
如果我在命令行执行我的 find 命令,它工作正常,但如果我在脚本中尝试它,我会收到此错误。我运行命令
FILTER=" | grep -v \"test\""
files=`find . -type f -regex \".*$ext\" $FILTER`
Run Code Online (Sandbox Code Playgroud)
如果我做
echo "find . -type f -regex \".*$ext\" $FILTER"
Run Code Online (Sandbox Code Playgroud)
它输出
find . -type f -regex ".*.cpp" | grep -v "test"
Run Code Online (Sandbox Code Playgroud)
在命令行上工作正常。我怎样才能让它在脚本中工作?我也尝试转义 *,但得到相同的错误。
我也注意到
find . -type f -regex \".*$ext\"
Run Code Online (Sandbox Code Playgroud)
在我的 shell 脚本中运行时没有输出,我不知道为什么,因为就像上面一样,如果我在命令行运行它,我会得到一个 .cpp 文件列表。
我有一个包含文件的文件夹
a1.cpp
a2.cpp
a3.cpp
a4.cpp
a5.cpp
a6.cpp
Run Code Online (Sandbox Code Playgroud)
我希望将 2 到 5 范围内的文件扩展名更改为 .java
如何在不使用循环的情况下在 xargs 的帮助下重命名这些文件?
最终输出将是
a1.cpp
a2.java
a3.java
a4.java
a5.java
a6.cpp
Run Code Online (Sandbox Code Playgroud) In powershell I'm used to doing something like this:
> $python_files = get-childitem *.py
> echo $python_files[0]
Run Code Online (Sandbox Code Playgroud)
The second command allows me to extract the first file, since get-childitem returns an array-like object.
In bash, I know the following is roughly equivalent:
> test=$(find . -iname '*.py')
Run Code Online (Sandbox Code Playgroud)
when I echo $test[0] however, I don't get the first item, so I think find returns a string like object.
Is there a generic way to obtain the first item from a find …
有几个问题可以解决问题,但我想尝试以下方法:
在这个问题中,我基本上将数组作为环境变量,然后尝试将字符串存储到单独的数组元素中。
a=('Apple Tomato' 'Banana Carrot') bash -c \
'b=($(echo "${a}")); echo -e "${b[0]}\n"; echo "${b[1]}";'
Run Code Online (Sandbox Code Playgroud)
(Apple
Tomato
Run Code Online (Sandbox Code Playgroud)
苹果番茄
香蕉胡萝卜
此外,如果原始数组在单引号数组元素内有双引号,是否会保留引号。例如:a=('Apple "Tomato"' 'Banana "Carrot"')