К сожалению, в странице справочника говорится это sort <no options> | join <no options>
не работает:
Important: FILE1 and FILE2 must be sorted on the join fields. E.g., use ` sort -k 1b,1 ' if `join' has no options, or use ` join -t '' ' if `sort' has no options.
Таким образом, Вы могли попробовать:
sort flash_int_list.txt | join -t '' finish_comm - > t1
или:
sort -k 1b,1 flash_int_list.txt | join finish_comm - > t1
Недавно я хотел сделать это с помощью tar
. Некоторое расследование показало мне, что то, что я не мог, было более чем бессмысленным. Я придумал эту странную split --filter = "cat> file; tar -r ..."
штуку, но она была ужасно медленной. И чем больше я читал о tar
, тем более бессмысленным он казался.
Видите ли, tar
- это просто составной список записей. Составляющие файлы никоим образом не изменяются - они целиком внутри архива. Но они заблокированы на границах 512-байтового блока , и перед каждым файлом стоит заголовок . Вот и все. Формат заголовка действительно очень прост.
Итак, я написал свой собственный tar
. Я называю это ... шитар
.
z() (IFS=0; printf '%.s\\0' $(printf "%.$(($1-${#2}))d"))
chk() (IFS=${IFS#??}; set -f; set -- $(
printf "$(fmt)" "$n" "$@" '' "$un" "$gn"
); IFS=; a="$*"; printf %06o "$(($(
while printf %d+ "'${a:?}"; do a=${a#?}; done 2>/dev/null
)0))")
fmt() { printf '%s\\'"${1:-n}" %s "${1:+$(z 99 "$n")}%07d" \
%07o %07o %011o %011o "%-${1:-7}s" ' 0' "${1:+$(z 99)}ustar " %s \
"${1:+$(z 31 "$un")}%s"
}
Это действительно мясо с картошкой. Он записывает заголовки и вычисляет chksum - что, условно говоря, является единственной сложной частью. Он выполняет формат заголовка ustar
... возможно . По крайней мере, он имитирует то, что GNU tar
, похоже, считает форматом заголовка ustar
, до такой степени, что не жалуется. И это еще не все, просто я еще не коагулировал его. Здесь я покажу вам:
for f in 1 2; do echo hey > file$f; done
{ tar -cf - file[123]; echo .; } | tr \\0 \\n | grep -b .
0:file1 #filename - first 100 bytes
100:0000644 #octal mode - next 8
108:0001750 #octal uid,
116:0001750 #gid - next 16
124:00000000004 #octal filesize - next 12
136:12401536267 #octal epoch mod time - next 12
148:012235 #chksum - more on this
155: 0 #file type - gnu is weird here - so is shitar
257:ustar #magic string - header type
265:mikeserv #owner
297:mikeserv #group - link name... others shitar doesnt do
512:hey #512-bytes - start of file
1024:file2 #512 more - start of header 2
1124:0000644
1132:0001750
1140:0001750
1148:00000000004
1160:12401536267
1172:012236
1179: 0
1281:ustar
1289:mikeserv
1321:mikeserv
1536:hey
10240:. #default blocking factor 20 * 512
Это tar
. Все дополнено \ 0
нулями, поэтому я просто превращаю em
в \ n
ewlines для удобства чтения. И ситар
:
#the rest, kind of, calls z(), fmt(), chk() + gets $mdata and blocks w/ dd
for n in file[123]
do d=$n; un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n%s\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"; cat "$d"
printf "$(x=$(($4%512));z $(($4>512?($x>0?$x:512):512-$4)))"
done |
{ dd iflag=fullblock conv=sync bs=10240 2>/dev/null; echo .; } |
tr \\0 \\n | grep -b .
0:file1 #it's the same. I shortened it.
100:0000644 #but the whole first file is here
108:0001750
116:0001750
124:00000000004
136:12401536267
148:012235 #including its checksum
155: 0
257:ustar
265:mikeserv
297:mikeserv
512:hey
1024:file2
...
1172:012236 #and file2s checksum
...
1536:hey
10240:.
Я говорю вроде там, потому что это не ситар
цель - tar
уже делает это красиво. Я просто хотел показать, как это работает - а это значит, что мне нужно коснуться chksum
. Если бы не это, я бы просто удалил dd
заголовок файла tar
и покончил с этим. Иногда это может даже сработать, но когда в архиве несколько участников, это становится беспорядочным. Тем не менее, chksum действительно прост.
Во-первых, сделайте это 7 пробелов - (я думаю, что это странная вещь GNU, поскольку в спецификации указано 8, но что бы то ни было - хак - это хак) . Затем сложите восьмеричные значения каждого байта в заголовке. Это твой чксум. Таким образом, вам нужны метаданные файла до того, как вы создадите заголовок, иначе у вас нет chksum. И это в основном архив устар
.
Хорошо. Теперь, что он предназначен для выполнения:
cd /tmp; mkdir -p mnt
for d in 1 2 3
do fallocate -l $((1024*1024*500)) disk$d
lp=$(sudo losetup -f --show disk$d)
sync
sudo mkfs.vfat -n disk$d "$lp"
sudo mount "$lp" mnt
echo disk$d file$d | sudo tee mnt/file$d
sudo umount mnt
sudo losetup -d "$lp"
done
Это создает три образа дисков по 500 Мбайт, форматирует и монтирует каждый и записывает файл в каждый.
for n in disk[123]
do d=$(sudo losetup -f --show "$n")
un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n$(lsblk -bno SIZE "$d")\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"
sudo cat "$d"
sudo losetup -d "$d"
done |
dd iflag=fullblock conv=sync bs=10240 2>/dev/null |
xz >disks.tar.xz
Примечание - очевидно, что блочные устройства всегда будут правильно блокироваться. Довольно удобно.
Этот tar
является содержимым файлов дискового устройства в потоке и направляет вывод в xz
.
ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
Теперь момент истины ...
xz -d <./disks.tar.xz| tar -tvf -
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk1
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk2
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk3
Ура! Извлечение ...
xz -d <./disks.tar.xz| tar -xf - --xform='s/[123]/1&/'
ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk11
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk12
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk13
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
Сравнение ...
cmp disk1 disk11 && echo yay || echo shite
yay
И крепление ...
sudo mount disk13 mnt
cat mnt/*
disk3 file3
Итак, в этом случае shitar
работает нормально, я полагаю. Я бы предпочел не вдаваться в подробности, которые он не сделает хорошо. Но, я скажу - по крайней мере, не делайте символы новой строки в именах файлов.
Вы также можете - и, возможно, должны, учитывая предложенные мной альтернативы - это с squashfs
. Вы не только получаете единственный архив, созданный из потока - , но и mount
способный и встроенный в ядро vfs
:
From псевдо -file.example :
# Copy 10K from the device /dev/sda1 into the file input. Ordinarily
# Mksquashfs given a device, fifo, or named socket will place that special file
# within the Squashfs filesystem, this allows input from these special
# files to be captured and placed in the Squashfs filesystem.
input f 444 root root dd if=/dev/sda1 bs=1024 count=10
# Creating a block or character device examples
# Create a character device "chr_dev" with major:minor 100:1 and
# a block device "blk_dev" with major:minor 200:200, both with root
# uid/gid and a mode of rw-rw-rw.
chr_dev c 666 root root 100 1
blk_dev b 666 0 0 200 200
Вы также можете использовать btrfs (send | receive)
для потоковой передачи вложенного тома в любой компрессор с поддержкой stdin
, который вам нравится. Конечно, этот подобтом не должен существовать, прежде чем вы решите использовать его в качестве контейнера сжатия.
Тем не менее, насчет сквошов
...
Я не верю, что делаю это справедливо. Вот очень простой пример:
cd /tmp; mkdir ./emptydir
mksquashfs ./emptydir /tmp/tmp.sfs -p \
'file f 644 mikeserv mikeserv echo "this is the contents of file"'
Parallel mksquashfs: Using 6 processors
Creating 4.0 filesystem on /tmp/tmp.sfs, block size 131072.
[==================================================================================|] 1/1 100%
Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,...
###...
###AND SO ON
###...
echo '/tmp/tmp.sfs /tmp/imgmnt squashfs loop,defaults,user 0 0'|
sudo tee -a /etc/fstab >/dev/null
mount ./tmp.sfs
cd ./imgmnt
ls
total 1
-rw-r--r-- 1 mikeserv mikeserv 29 Aug 20 11:34 file
cat file
this is the contents of file
cd ..
umount ./imgmnt
Это только встроенный -p
аргумент для mksquash
. Вы можете создать файл с помощью -pf
, содержащий столько файлов, сколько захотите. Формат прост - вы определяете имя / путь к целевому файлу в файловой системе нового архива, вы указываете ему режим и владельца, а затем указываете ему, какой процесс выполнять и откуда читать stdout. Вы можете создавать сколько угодно - и вы можете использовать LZMA, GZIP, LZ4, XZ ... хм, есть еще ... форматы сжатия, какие захотите. И конечный результат - это архив, в который вы cd
.
Подробнее о формате:
Это, конечно, не просто архив - это сжатый монтируемый образ файловой системы Linux. Его формат - это ядро Linux - это файловая система, поддерживаемая ванильным ядром. Таким образом, он так же распространен, как и ванильное ядро Linux. Так что, если бы вы сказали мне, что используете обычную систему Linux, на которой не установлена программа tar
, я бы усомнился, но я бы, вероятно, вам поверил.Но если бы вы сказали мне, что используете обычную систему Linux, в которой файловая система squashfs
не поддерживается, я бы вам не поверил.
Ваша проблема какое-то время меня озадачивала, и я думаю, что нашел решение, которое сработает.
Я думаю, что вы можете добиться желаемого с 7z, используя флаг -si {NAME}
.
Вы сможете адаптироваться к своим потребностям.
7z a test.7z -siSDA2.txt < /dev/sda1
7z a test.7z -siSDA2.txt < /dev/sda2
7z l test.7z
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)
Listing archive: test.7z
--
Path = test.7z
Type = 7z
Method = LZMA
Solid = -
Blocks = 2
Physical Size = 1770
Headers Size = 162
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2014-08-19 22:01:08 ..... 6314 804 SDA1.txt
2014-08-19 22:01:11 ..... 6314 804 SDA2.txt
------------------- ----- ------------ ------------ ------------------------
12628 1608 2 files, 0 folders
ИЗМЕНИТЬ : Убрать бесполезное использование кота
Если вам все равно, делает это tar или нет, и все, что вам нужно, это архив содержимого блочного устройства, вы можете использовать ddrescue, который создаст двоичный образ устройства с именем файла по вашему выбору.. Программа установки (для Debian )называется gddrescue.
После того, как образ создан, вы можете использовать любую программу записи образов для его восстановления, и вы даже можете смонтировать образ, чтобы увидеть (и скопировать )то, что внутри него.