[英]How do I make an array of specific files in a directory using the command shell in linux?
I have been trying to add files smaller than 2 Megabytes in a directory to an array and then add those files to git and then commit. 我一直在尝试将目录中小于2 MB的文件添加到数组中,然后将这些文件添加到git中,然后提交。
find . -type f -size -2M
i=0
while read line
do
array[ $i ]="$line"
(( i++ ))
done
for item in "${array[@]}"
do
git add "$item"
done
git commit -am "${COMMIT_MESSAGE}"
The script is supposed to add and commit files below 2M. 该脚本应在2M以下添加和提交文件。 But my script is adding and committing all the files (including the ones larger than 2M). 但是我的脚本是添加并提交所有文件(包括大于2M的文件)。 What am I doing wrong? 我究竟做错了什么?
Use find
to run git add
. 使用find
运行git add
。
find . -type f -size -2M -exec git add {} +
This will work for all valid file names. 这将适用于所有有效文件名。
The -a
option to commit
is probably not necessary. 可能不需要-a
选项来commit
。 If you only have untracked large files, they won't be added by commit -a
anyway, and you've already added all the modified small files. 如果只有未跟踪的大文件,则无论如何都不会通过commit -a
添加它们,并且您已经添加了所有修改后的小文件。 However, you do need to drop it if you have large tracked files with modifications that you don't want to include in the pending commit. 但是,如果跟踪文件较大且不想将其包含在挂起的提交中,则需要删除它。
First, with respect to correctly reading files from find
, follow the advice in @chepner's answer . 首先,关于正确读取find
文件,请遵循@chepner的答案中的建议。
Second, as to why your existing code includes all files already added to git in some past revision, as opposed to only those under 2MB, despite not running git add
at all : That's because you're passing the -a
argument to git commit
. 其次,至于为什么你现有的代码包括已经添加在过去的一些修改与git的所有文件,而不是只有2MB下,尽管没有运行git add
都 :那是因为你传递的-a
参数git commit
。
find . -type f -size -2M -exec git add -- {} +
git commit -m "Commit message" # no -a here!
To be clear as to what I mean by "despite not running git add
at all " above -- as currently written, the output of find
isn't actually passed into the while read
loop. 为了能够清楚我所说的“尽管没有运行意味着git add
在所有 ”上面-因为当前被写入,输出find
实际上并没有传递到while read
循环。
find .
while read ...
doesn't redirect the output of find
into the while read
loop. 不会将find
的输出重定向到while read
循环中。 Thus, your while read line
loop iterates only on input given to your script on stdin, if any (and the output of find
is written to stdout). 因此,您的while read line
循环仅在stdin上给脚本的输入(如果有的话)上进行迭代(并将find
的输出写入stdout)。
For other issues, see notes below. 对于其他问题,请参见下面的注释。
Now, to answer your literal question, about how to build a shell array, doing it right looks like the following: 现在,要回答有关如何构建shell数组的字面上的问题,正确执行如下操作:
# correctly building a shell array
files=( )
while IFS= read -r -d '' file; do
files+=( "$file" )
done < <(find . -type f -size -2M -print0)
## using that array efficiently (if not huge)
#git add -- "${files[@]}"
# using that array efficiently (if potentially huge)
printf '%s\0' "${files[@]}" | xargs -0 git add --
Implementation notes: 实施说明:
while
loop in the outer shell ensures that changes to variable state that it makes are accessible after it finishes running. 将while
循环放入外壳可确保在完成运行后可以访问对其所做的可变状态的更改。 Using the < <(...)
idiom is necessary to do so, as given in BashFAQ #24 . 如BashFAQ#24中所述 ,必须使用< <(...)
习惯用法。 git add
instance is much more efficient than calling git add
once per file. 将多个文件传递到一个git add
实例比每个文件调用一次git add
效率更高。 -print0
argument to find
causes filenames to be separated by NULs (which, unlike newline literals, cannot possibly exist in filenames) in find
's output. 使用-print0
参数find
原因的文件名由完全无效的(它不同于新行文字,不可能在文件名中存在的话)中分离find
的输出。 IFS= read -r -d '' file
idiom (as described in BashFAQ #1 ) reads names from find
in byte-for-byte literal form. 使用IFS= read -r -d '' file
惯用法(如BashFAQ#1中所述 )以逐字节文字形式从find
中读取名称。 array+=( "$value" )
is much, much easier than keeping an integer index counter and incrementing it between each append. 使用array+=( "$value" )
比保留整数索引计数器并在每个追加之间递增它容易得多。 Please try 请试试
find . -type f -size -2M -print0 | xargs -0 git add
git commit -m 'Message here'
the one-line command from the first comment is good but if you still need a script in order to add some extra logic try to use this: 第一条注释中的单行命令很好,但是如果您仍然需要脚本来添加一些额外的逻辑,请尝试使用此命令:
#!/bin/bash
root_dir="/home/myuser/myproject"
exclude_path="dirname_to_exclude"
max_size="-2048k"
for file in $(find $root_dir -type f -size $max_size | grep -v $exclude_path)
do
git add $file
done
git commit -m "blablabla..."
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.