현재 디렉터리에서 모든 파일을 찾아 내용을 처리하기 전에 알파벳순으로 정렬하여 각 파일의 처음 3자를 추출하고 싶습니다. 이렇게 하면 다른 파일로 리디렉션할 수 있는 문장이 생성됩니다. 나는 이것을 시도했습니다 :
find . -type f -exec basename {} \; | sort | xargs head -c 3
하지만 나는 다음을 얻습니다.
헤드: 읽기 위해 'filenamehere'을 열 수 없습니다. 해당 파일이나 디렉터리가 없습니다.
모든 파일에 대해 처음 3자를 추출하려고 합니다. 먼저 정렬하지 않고 이 작업을 수행할 수 있었습니다.
답변1
편집하다: 처음:
find -type f -exec grep -I -q . {} \; -exec sh -c 'echo -e "$(basename "$0") {}"' {} \; | sort | cut -d ' ' -f2 | xargs sed -Ee 's/(^.{3})(.*)/\1/g'
grep -I -q . {} \;
이미지와 같은 바이너리 파일은 검색되지 않고 모든 텍스트 파일만 검색됩니다.
두번째:
내 기본 아이디어는 키가 기본 이름과 같고 값이 처음 3자와 같은 해시 함수를 만드는 것입니다.
#!/bin/bash
touch file_s
echo 'declare -A map' > file_s
find . ! -name file_s ! -name sort_map -type f -exec grep -I -q . {} \; \
-exec sh -c 'i="$(basename "$0")";echo "map["$i"]=$(head -n 1 "$0"|cut -c
1-3)" >> file_s;' {} \; | sort | while read -r line
do
source file_s
echo -e ${map["$line"]}
done
이 코드를 작성해야 하는 스크립트의 이름은 임시 sort_map
입니다 file_s
. 문서. 따라서 find 명령에 이 두 파일을 포함하면 안 됩니다. grep -I -q . {} \;
grep 파일을 바이너리 파일이 아닌 텍스트 파일로만 만듭니다.
두 번째 -exec
명령은 다음과 같습니다.
i="$(basename "$0")";
기본 이름을 가져와 변수 i에 기록합니다.
echo "map["$i"]=$(head -n 1 "$0"|cut -c 1-3)" >> file_s;
해시 함수와 해당 값을 임시 파일에 기록합니다 file_s
.
sort
파일 이름이 정렬됩니다.
while read -r line
do
source file_s
echo -e ${map["$line"]}
done
파일을 한 줄씩 읽고 가져옵니다 file_s
. 그러면 처음 3자가 인쇄됩니다.
head는 파일 이름이 아닌 파일 내용을 인쇄하므로 head를 사용할 수 없습니다.
당신은 그것을 사용할 수 있습니다 :
find . -type f -exec basename {} \; | sort | cut -c 1-3
b
또는 옵션을 대신 사용할 수 있지만 c
모든 문자가 1바이트라고 가정합니다.
find . -type f -exec basename {} \; | sort | cut -b 1-3
처음 세 문자를 가져옵니다.
당신은 그것을 사용할 수 있습니다 :
find . -type f -exec basename {} \; | sort | sed -Ee 's/(^.{3})(.*)/\1/g'
파일을 정렬한 다음 처음 세 문자를 일치시켜서만 인쇄합니다.
노트:이러한 모든 명령은 공백과 탭을 하나의 문자로 처리합니다.
답변2
basename
NET의 모든 파일에 대해 실행 하지 마십시오 find
. 발견된 모든 파일에 대해 셸을 실행하는 것은 엄청난 리소스 낭비입니다.
find
(GNU 버전을 가정하면 다른 버전에서도 이를 지원할 수 있습니다.) 파일 이름뿐만 아니라 크기, 소유권, 권한 등을 포함하여 파일에 대한 정보를 출력하는 방법을 알려주는 형식 문자열을 사용하는 find
지시문이 있습니다 .-printf
한 가지 형식은 사용 중인 형식 %f
인 파일 이름에서 모든 선행 디렉터리를 제거하는 것 입니다 . basename
그래서 당신은 사용할 수 있습니다
find -type f -printf '%f\n'
\n
각 파일 이름이 한 줄에 표시되도록 줄바꿈을 추가해야 합니다 .
또 다른 장점은 이 방법으로 인쇄할 문자 수에 제한을 추가할 수 있다는 것입니다. 최대 3자의 파일 이름을 인쇄하려면 다음을 사용하십시오.
find -type f -printf '%.3f\n'
이제 sort
믹스에 추가하세요.
find -type f -printf '%.3f\n' | sort
당신은 당신의 솔루션을 가지고 있습니다.
편집: 파일을 정렬한 다음 해당 내용의 처음 3자를 출력해야 하는 것처럼 보이므로 명령은 다음과 같습니다.
find -type f -printf '%f\t%p\n' | sort | cut -f2 | xargs head -n 1 | cut -c1-3
이는 형식 문자열을 사용하여 먼저 기본 파일 이름만 표시한 다음 탭, 마지막으로 전체 경로를 표시합니다. 파일 이름을 쉽게 정렬하는 데 사용할 수 있습니다.
cut -f2
탭 뒤 부분만 추출합니다.
xargs head -n 1
각 파일의 첫 번째 줄을 가져옵니다.
cut -c1-3
각 줄의 처음 세 문자를 표시합니다.
이 head -n 1
부분은 파이프라인에 필요합니다. 그렇지 않으면 cut
각 파일의 각 줄의 처음 3자가 표시됩니다.
답변3
GNU 헤드(용 -q
) 및 쉘의 기본 와일드카드 확장 정렬을 사용하십시오.
head -q -c 3 * > /tmp/output
또는,
for file in *; do dd status=none if="$file" bs=1 count=3; done > /tmp/output
파일이 단일 하위 디렉터리에 있는 경우(기준:당신의 별도 의견) 그런 다음 와일드카드를 조정합니다.
head -q -c 3 /directory/subdirectory/* > /tmp/output
그리고
for file in /directory/subdirectory/* # ...
답변4
그래서 나는 마침내 답변에서 영감을 얻은 나만의 솔루션으로 이 문제를 해결했습니다. 1개가 아닌 3개의 명령으로 수행해야 했습니다. 나는 이걸했다:
mkdir holder
find . -type f -exec mv -t holder {} \;
head -qc 3 ./holder/* > prophetie.txt
이렇게 하면 전체 문장이 원하는 대로 왼쪽에서 오른쪽으로 흐르게 됩니다. 내가
ls -l holder
그것들은 모두 알파벳 순서로 되어 있습니다. 이 작업을 수행할 때 정렬할 필요조차 없습니다. mv 명령이 정렬하는 것 같나요?