Как я могу разделить текстовый файл на основе содержания в несколько текстовых файлов?

Если Вы используете команду ls -n Вы видите UIDs на данном смонтированном диске/разделе.

$ ls -n
total 24
drwxrwxr-x 2 500 501  4096 May 24 15:44 bin
-rw-rw-r-- 1 500 501 11650 May 24 15:44 bouncer.log
drwxrwxr-x 5 500 501  4096 May 23 14:56 testdata
drwxrwxr-x 5 500 501  4096 May 24 14:55 testresults

Можно также использовать stat команда для наблюдения большего количества деталей о UID/GID данного файла:

$ stat bouncer.log 
  File: `bouncer.log'
  Size: 11650       Blocks: 24         IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 11023682    Links: 1
Access: (0664/-rw-rw-r--)  Uid: (  500/    saml)   Gid: (  501/    saml)
Access: 2013-05-24 15:44:17.322878327 -0400
Modify: 2013-05-24 15:44:25.484211596 -0400
Change: 2013-05-24 15:44:25.484211596 -0400

UIDs являются абсолютными. Они - то, что находится в системе. Имена отображаются в различными инструментами такой как ls путем взгляда в системе /etc/passwd и /etc/group файлы.

Если число не представлено ни в одном из этих файлов затем число UID/GID, это находится на диске, то, что отображено.

Это - обязанность системного администратора удостовериться, что подобные UIDs/GIDs через диски являются действительно тем же пользователем и/или группой. Unix не обеспечивает механизма для гарантии этого для Вас.

4
24.04.2014, 02:12
3 ответа
awk '/^4153/ {print >"CAMS1.TXT"; next} {print >"CAMS2.TXT"}' CAMS.TXT

Есть и другие способы сделать это, другой - использовать две команды grep

grep "^4153" CAMS.TXT > CAMS1.TXT
grep -v "^4153" CAMS.TXT > CAMS2.TXT

Это менее эффективно, но легче набирать текст, после того, как сделано первое grep, вы вспоминаете его из истории оболочки (используя клавишу со стрелкой "вверх") и вносите несколько изменений. Конечно, файл читается дважды, так что не делайте этого, если он огромный.

5
27.01.2020, 20:47

Вот чистый вариант bash на более общем решении terdon.

while read line; do 
  echo "$line" >> "${line:0:4}.txt"
done < CAMS.txt

Полученные файлы будут именоваться в соответствии с первыми четырьмя символами в каждой строке, например 4153.txt и 4801. txt для входа-образеца.

Следующий фрагмент может быть использован для пакетного переименования результирующих файлов в CAMS1.txt, CAMS2.txt и т.д. (предполагая, что первые четыре символа каждой строки в исходном входе на самом деле были цифрами).

i=1
for file in [0-9][0-9][0-9][0-9].txt; do
  mv "$file" "CAMS$(( i++ )).txt"
done

Это основано на наблюдении, что цифры в исходном входном файле находятся в возрастающем порядке, а нумерация файлов образца выходных файлов соответствует этому порядку.

Пояснение:

while read line; do 
  ...
done < CAMS.txt

Итерифицирует файлCAMS.txt, считывая каждую строку по очереди в переменную строку.

echo "$line" >> "${line:0:4}.txt"

Присоединяет обрабатываемую в данный момент строку к файлу, имя которого получено из первых четырех символов текущей строки.


i=1

Присваивает значение 1 переменной i.

for file in [0-9][0-9][0-9][0-9].txt; do
  ...
done

Итерифицирует файлы в текущей директории, которые имеют четыре цифры в своем имени и заканчиваются расширением .txt. Файл [0-9][0-9][0-9].txt в вышеупомянутом фрагменте называется shell glob. Эта функция может быть использована для сопоставления или расширения определенных типов шаблонов, в данном случае имен файлов.

mv "$file" "CAMS$(( i++ )).txt"

Переименуйте файл , который в настоящее время обрабатывается. Имя целевого файла "CAMS$((( i++ )).txt" состоит из префикса CAMS, связанного с текущим значением переменной i. Переменная i одновременно инкрементируется в арифметическом выражении bash bash, как указывает синтаксис (( ... )), с использованием постфиксного оператора инкремента ++. Дополнительный $ до (( ... )) вызывает значение выражения, в данном случае значение i до инкремента, которое должно быть развернуто в строку, указывающую имя файла-получателя. Наконец, к имени файла назначения добавляется суффикс .txt.

.
2
27.01.2020, 20:47

В этом конкретном случае, когда вы уже знаете текст, вы можете сделать что-то вроде

while read line; do 
    [[ $line =~ ^4153 ]] && 
        printf "%s\n" "$line" >> CAMS1.TXT || 
        printf "%s\n" "$line" >> CAMS2.TXT 
done < CAMS.TXT 

Это считывает каждую строку CAMS.TXT в переменную $ line , а затем, если $ line начинается с 4153, он печатает в CAMS1 а если нет, он печатает в CAMS2.

В качестве альтернативы, вы можете вывести каждую строку в стандартный поток ошибок или стандартный вывод в зависимости от первых чисел и соответствующим образом перенаправить вывод команды. Например:

perl -ne '/^4153/ ? print STDOUT : print STDERR' CAMS.TXT >CAMS1.TXT 2>CAMS2.TXT 

Если вы не знаете, каким будет текст, вы можете просто записать каждую строку в файл, имя которого состоит из первых 4 символов строки:

awk '{print >> substr($1,1,4)}' CAMS.TXT 

Приведенное выше создаст два файла, 4153 и 4801 , каждый из которых содержит ожидаемые строки. Это дает преимущество работы с любым количеством различных шаблонов.

4
27.01.2020, 20:47

Теги

Похожие вопросы