Avoid matching . and .. when looping through files in POSIX shell

匆匆过客 提交于 2019-12-24 07:47:02

问题


I want to do something to every file in a directory, so I have

for f in /path/* /path/.*; do
  [ -e "$f" ] || continue
  do_thing "$f"
done

Unfortunately, this also matches . and .., which is undesirable in this case. How can I avoid matching . and ..?


回答1:


To run do_thing on every file in the current directory, try:

find /path -maxdepth 1 -type f -exec do_thing {} \;

This method avoids looping and avoids parsing ls.

How it works

  • find /path

    This starts a find command and tells find to look in directory /path.

  • -maxdepth 1

    This tells find to look only in the current directory and not to descend into subdirectories.

  • -type f

    This tells find that we are only looking for regular files (not directories).

  • -exec do_thing {} \;

    This runs command do_thing on every file found.




回答2:


How about using if to avoid them?

tmp_path=/path
for f in $tmp_path/* $tmp_path/.*; do
  if [ "$f" == "$tmp_path/." ] || [ "$f" == "$tmp_path/.." ]
  then
    continue
  fi
  [ -e "$f" ] || continue
  echo "$f"
done



回答3:


the following should match all the hidden files and exclude both . and ..

for f in `ls -a /path | grep -vE "^\.{1,2}$"`; do
    # whatever
done

-v inverts the match, \. matches the literal dot, {1,2} matches it once or twice, ^ and $ match the start and end of line, respectively. the -E flag makes the {m,n} syntax work. The backticks ` prevent the shell choking on the pipe. (hihi)




回答4:


clean_path=`ls -a ~/example_dir/ | grep -v -P "^\.{1,2}$"`
for f in $clean_path; do
    do_thing $f;
done

ls -a ~/some_dir command to print out all of the file in the some_dir directory.

^\.{1,2}$ means, match a string which start (^) with dot (\.), the dot may come in 1 to 2 characters ({1,2}), and that's the end of the string ($), so it will match both . and ...

Using backtick within a command means "process the result of this command".

grep -v -P, -v flag to inverse the answer, so it would exclude the matching file that named . and ... -P flag to use the Perl regular expression.

Voila, you can now iterate them since the result is only separated by space.



来源:https://stackoverflow.com/questions/56928816/avoid-matching-and-when-looping-through-files-in-posix-shell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!