简体   繁体   English

如何在Linux中使用命令Shell在目录中创建特定文件的数组?

[英]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. 但是,如果跟踪文件较大且不想将其包含在挂起的提交中,则需要删除它。

Short form: Resolving the immediate problem 简短形式:解决眼前的问题

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!

Long form: Explaining the problem 长格式:说明问题

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. 对于其他问题,请参见下面的注释。


Long form: Answering the question as-asked 长格式:按要求回答问题

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: 实施说明:

  • Putting the 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所述 ,必须使用< <(...)习惯用法。
  • Passing multiple files to a single git add instance is much more efficient than calling git add once per file. 将多个文件传递到一个git add实例比每个文件调用一次git add效率更高。
  • Using the -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的输出。
  • Using the 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中读取名称。
  • Using 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.

相关问题 如何使用Linux命令或Shell脚本读取特定行的文件 - How to read specific line of files with a Linux command or Shell Script 如何使用 bash 脚本在 linux 中创建命令? - How do I make a command in linux using a bash script? 如何通过Linux中的shell脚本创建新目录? - How do I create a new directory through a shell script in Linux? 如何在LINUX的另一个目录中有选择地创建指向特定文件的符号链接? - How do I selectively create symbolic links to specific files in another directory in LINUX? 我如何从另一个目录访问目录中的文件(linux) - how do i access files in directory from another directory (linux) 如何在python中执行复杂的“find”linux shell命令 - How do I execute a complex “find” linux shell command in python 如何在 Linux 上启动时运行 shell 命令? - How do I run a shell command on startup on Linux? 如何使用 Linux 命令找到我的 shell 版本? - How can I find my shell version using a Linux command? 如何使用bash脚本列出Linux目录中的所有文件? - How do I list all files in a directory in Linux using bash script? 如何在 linux 中的 discord.py 中发出重启命令? 即使它需要像 shell 之类的其他文件 - How to make a restart command in discord.py in linux? even if it needs another files like shell or something
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM