파일 관리자에서는 일반적으로 파일을 선택한 다음 Shift다른 파일을 길게 선택할 수 있습니다. 그 사이의 모든 파일이 선택됩니다.
나는 하고 싶다 bash
/ zsh
이것과 동등하다.
예: 2개의 파일 이름을 지정하고 싶습니다. 각 파일 이름은 중간에 있습니다(알파벳 순서 - ls
출력 방식).
및 기타 와일드카드 옵션을 알고 있지만 ? {} *
이름이 매우 혼란스러운 파일에 사용할 수 있기를 바랍니다.
예를 들어:주어진 파일
$ ls
aoeitoae.txt
oaeistn.txt
oaie.txt
paeoai.txt
sotaoe.txt
다음과 같은 명령을 실행하여 다음을 얻고 싶습니다 rm aoeitoae.txt-oaie.txt
.
$ ls
paeoai.txt
sotaoe.txt
이 목표를 어떻게 달성할 수 있나요?
답변1
이 답변은 주로 zsh에 대한 것입니다. 대부분의 작업은 bash에서는 쉽게 수행할 수 없습니다.
많은 일반적인 상황에서 사용할 수 있습니다.와일드카드. 특히:
- 모든 것이 함께 제공됩니다고정 접두사:
foo-*
- 모든 것이 함께 제공됩니다고정 접두사 뒤에 범위 내의 다른 문자가 옵니다.: ( , , 를
foo[b-m]*
포함 하지만 또는 제외 )foobar
food
foomz1
fooar
foon
- 특정 범위 내의 숫자:
IMG-<7-42>.*
(포함IMG-8.PNG
및IMG-0042.JPG
제외IMG-77.JPG
)
그리고글로벌 예선, 식별하는 간단한 방법이 있습니다.범위이지만 개수가 필요함: 파일이 무엇이든 상관없이 foo*([1,3])
나열된 처음 3개 파일과 일치합니다 foo*
(3개 미만인 경우 모든 파일과 일치). foo*(om[1,3])
이는 로 시작하는 이름 일치 와 같은 정렬이 완료된 후에 발생합니다 foo
.
zsh에게 숫자를 알아내도록 요청할 수 있습니다. 두 단계로 수행합니다. 먼저 모든 일치 항목을 배열에 넣은 다음 다음을 사용합니다.아래 첨자 기호 i
( 와일드카드 일치를 방지하려는 I
경우 e
): 요소 간 배열 부분(포함 $a[$a[(i)foo],$a[(I)bar]]
)이거나 존재하지 않는 경우 비어 있습니다.$a
foo
bar
foo
bar
a=(*.txt(oL))
# List the files that appear between small.txt and large.txt in a listing by size.
# Note that files that have the same size as one of the bounds may or may not be included.
echo $a[$a[(I)small.txt],$a[(I)large.txt]]
그래서 이것은 구현하는 함수입니다.질문의 요구 사항을 완전히 충족합니다.(정확한 구문을 제외하고는 이 작업을 수행할 수 없습니다):
# Usage: select_range FROM TO WILDCARD_PATTERN
# Sets the array $s to the files matching PATTERN from FROM to TO inclusive.
function select_range {
if (($# < 2)); then
echo >&2 "select_range: missing range arguments"
return 120
fi
local from=$1 to=$2
shift 2
from=$@[(ie)$from]
if ((from == 0)); then
echo >&2 "select_range: not matched: $from"
fi
to=$@[(Ie)$to]
if ((to == 0)); then
echo >&2 "select_range: not matched: $from"
fi
s=($@[$from,$to])
}
용법:select_range aoeitoae.txt oaie.txt * && rm $s
glob e
한정자를 사용하면 임의의 코드를 작성하여 결과를 필터링할 수 있지만 약간 다루기 어려워지기 시작했습니다. 복잡한 경우에는 인용이 까다로울 수 있습니다. 단순화를 위해 '
구분 기호(백슬래시로 인용해야 함)로 사용하고 필터 코드를 작은따옴표로 묶어 패턴이 다음과 같습니다 foo-*(e\''code goes here'\')
. (인용이 너무 복잡해지면 함수를 작성하고 한정자를 사용하세요 +
.) 필터링 aoeitoae.txt
전과 필터링 전의 파일oaie.txt
사전순으로: *(e\''! [[ $REPLY < aoeitoae.txt || $REPLY > oaie.txt ]]'\')
.
필터에서 수행된 비교는 반드시 와일드카드 확장과 동일한 순서를 사용하지는 않습니다. 예를 들어, thanks 한정자는 foo-*(n)
앞에 나열되어 있지만 문자열 비교에서는foo-9
foo-10
n
[[ foo-9 > foo-10 ]]
가정 어구정수 하위 문자열의 수치 비교 와 유사한 >
연산자입니다 . 하나 만들고 싶다면문자열과 숫자로 정렬된 정수 부분의 비교,당신은 그것을 사용할 수 있습니다n
매개변수 확장 플래그배열을 정렬하고 중간에 일치하는 이름이 유지되는지 확인합니다. , , , ... *(ne\''a=(b11r $REPLY f10o); [[ $a[2] == "${${(@n)a}[2]}" ]]'\'))
는 포함 하지만 , , ... 은 포함하지 않습니다.b101r
b11s
d1
f02o
b9r
f011
날짜별로 파일을 일치시키는 경우 조건을 사용할 수 있습니다 (파일은 자체 -nt
파일보다 최신이 아님).*(ome\''! [[ $REPLY -ot from || $REPLY -nt to ]]'\')
사이에 수정된 파일의 수정 시간 from
과 의 수정 시간 to
(포함)입니다.
답변2
Bash 기능을 사용하세요:
sfiles ()
(
# run this in a subshell, so we don't have to care if nullglob/dotglob were enabled or not
[ $# -eq 0 ] && exit
local nullsep=0
if [ "$1" = "-0" ]; then
nullsep=1; shift
fi
local first=$1
shift $(($# -1))
local last=$1
local files=( )
shopt -s nullglob dotglob
for i in *; do
# first argument found or array not empty?
if [ "$i" = "$first" ] || [ "${#files[@]}" -ne 0 ]; then
files+=( "$i" )
fi
# last argument found? break loop
[ "$i" = "$last" ] && break
done
if [ "${#files[@]}" -gt 0 ]; then
[ "$nullsep" -eq 1 ] &&
printf '%s\0' "${files[@]}" ||
printf '%s\n' "${files[@]@Q}"
fi
)
첫 번째 인수와 마지막 인수(포함) 사이의 모든 파일을 출력합니다.
예:
$ ls -A
btjhyyxrlv.txt otewagahzp.txt .xxx
crlcsbzizl.txt ssffszhdmp.txt 'zdjtgahx q.txt'
hgiagchkgt.txt 'tt'$'\t''aa.txt' 'zmwik zhur.txt'
jusupbivit.txt umikyfucgu.txt 'z otmleqlq.txt'
' kcyigyurc.txt' ' upvpntdfv.txt' .zzz
kfthnpgrxm.txt 'uu'$'\t\t''aa.txt'
lgzsmquxwj.txt wlwexgzohs.txt
$ sfiles c* k*
'crlcsbzizl.txt'
'hgiagchkgt.txt'
'jusupbivit.txt'
' kcyigyurc.txt'
'kfthnpgrxm.txt'
$ sfiles .xxx .zzz
'.xxx'
'zdjtgahx q.txt'
'zmwik zhur.txt'
'z otmleqlq.txt'
'.zzz'
$ LC_ALL=C sfiles .xxx .zzz
'.xxx'
'.zzz'
잘못된 순서입니다. 아무것도 반환하지 않습니다.
$ sfiles .zzz .xxx
선택한 파일을 삭제하려면 다음 명령을 사용하십시오 xargs
.
$ sfiles .xxx .zzz | xargs rm
탭이나 줄 바꿈이 있는 파일 이름의 경우 -0
bash 인용 없이 null로 구분된 출력의 첫 번째 인수로 옵션을 추가합니다.
$ sfiles -0 tt* uu* | xargs -0 ls
'tt'$'\t''aa.txt' ' upvpntdfv.txt'
umikyfucgu.txt 'uu'$'\t\t''aa.txt'
답변3
이 작업을 수행하기 위해 자신만의 셸 함수를 작성할 수 있습니다. 모든 파일 목록을 가져오고 첫 번째 파일 이름 앞의 모든 파일과 두 번째 파일 이름 뒤의 모든 파일을 삭제합니다. 대략적으로 말하면 zsh에서는 이것이 bash에서 더 짜증날 것이라고 생각하기 때문입니다.
#!/usr/bin/zsh
filerange() {
# variable "reply" is an array
typeset -ag reply
reply=("$1")
# don't get upset if nothing matches
setopt nullglob
# get a complete list of candidate files
#allfiles=*(^/^on)
# ^--------- * glob
# ^----^--- (…) glob modifiers within parentheses
# ^------- ^ invert match
# ^------ / match directories (inverted: match all *but* dirs)
# ^----- ^ invert sort order (uninvert the above inversion)
# ^---- o order by:
# ^--- n character values of name
for fname in *(on^/); do
[[ ( "$2" > "${fname}" && "${fname}" > "$1" ) ]] \
&& reply+=("${fname}")
done
reply+=("$2")
}
$reply
이는 예를 들어 사용할 수 있는 멋지고 "안전한" 배열을 제공합니다 for
.
# prepare a test dir
mkdir /tmp/testdir
cd /tmp/testdir
sudo mknod blockdev b 1 1
sudo mknod chardev c 1 1
mkdir dir
mkfifo fifo
touch file
touch "file with spaces"
touch "file with\nnewlines"
touch "last file"
touch "ok one more file"
ln -s blockdev symlink
# This will look funny, because there's a file name with a new line in there
echo *
# Let's try this:
filerange chardev "last file"
# We're expecting to get all files from (incl) chardev to (incl) last file,
# but not `dir`, as that's a directory
for f in ${reply}; do;
echo "entry: ${f}"
done
parallel
물론, 이러한 파일(예: for 또는 ) 을 인쇄하고 싶다면 xargs
옵션을 -0
Freddy의 파일로 사용하는 함수를 작성하세요.좋은 대답일러스트는 탁월한 선택입니다! 이 함수는 매우 간단합니다. 'ing 루프에서 호출할 수 있고 from을 filerange
처리합니다 .$reply
printf
for
답변4
이것은 완전한 대답은 아니지만 awk
사용할 수 있는 훌륭한 범위 연산자가 있다는 점을 언급하고 싶었습니다.
$ ls | awk '/^aoeitoae\.txt$/,/^oaie\.txt$/ { print }'
aoeitoae.txt
oaeistn.txt
oaie.txt
이 awk
코드는 첫 번째 정규식과 일치하는 첫 번째 입력 줄부터 시작하여 두 번째 정규식과 일치하는 첫 번째 입력 줄로 끝나는 입력 줄을 인쇄합니다.
일치는 정규식을 사용하며 이 예에서는 인용되지 않으므로 파일 이름에 공백이나 기타 이상한 문자가 포함되어 예상치 못한 결과가 발생할 수 있습니다.
그리고아마도다음과 같은 텍스트 기반 파일 관리자를 사용해 보고 싶습니다.자정 사령관.