7pk
A tiny little script created for the convenience of archiving. If no file(s), folder(s) or filelist(s) (included with an @ at the beginning of the filename of the filelist, for example, @fl.txt) were given, the script will archive everything in the current folder by default.
This batch / bash script accepts optional switches as follows:
-por-p*: sets the password for the archive; if no password is provided immediately attached to the-pswitch (means you have to write in the form of-p123WSX), then 7-zip will prompt for a password to be set;-o: sets the name of the archive; if no-oswitch is found, the script will then pack the given files into a .7z archive with a 6-digit date string and a 4-digit time string (separated by a hyphen) of the time accurate to the minute of the archive being made as its filename; if-ois found, then the given filename will surpass the default naming pattern; this switch also accepts three naming cards as follows:[: if a[(left square bracket) is detected at the beginning of the given filename string (excluding the part of path—if specified) but no](right square bracket) is found in the rest part of that string, then a 6-digit date wrapped in square brackets will be added to the beginning of the filename, followed by a space character and the rest of the given filename without the leading[; for example,-o [abcshall produce something like ‘[260419] abc.7z’, where ‘260419’ stands for the date of the archive being made;_: if a_(underscore) is detected at the end of the given filename string (excluding the part of path—if specified), then a 6-digit date string and a 4-digit time string (separated by a hyphen) will be appended to the end of the filename without removing the given underscore; for example,-o abc_shall be processed into ‘abc_260419-2346.7z’, where ‘260419-2346’ stands for the date and time of the archive being made;`or=: if a`(backtick) is detected while using the batch script on Windows or an=(equals sign) is detected while using the bash script on Linux anywhere in the given filename string (excluding the part of path—if specified), then the`(on Windows) or the=(on Linux) will be replaced with the name of the current directory; for example, if the current directory is named ‘abc’, and if-o "[def `_"is passed to the script on Windows or if-o "[def =_"is passed to the script on Linux, then the final filename shall be ‘[260419] def abc_260419-2346.7z’;- the script will automatically remove any leading or trailing spaces in the filename of the archive and trim consecutive spaces of more than one into one, which means if the name of the current directory contains consecutive spaces and if it is referenced in the filename of the archive, it will be trimmed, but this won’t affect the path designated for the archive—if indeed specified with the filename, and if the path contains leading, trailing or consecutive spaces—these spaces in the path will be left untreated; and
- the script will also automatically detect and deal with the existence (or the non-existence) of the file extension in the given filename, to wit, ‘.7z’—if there is no extension given, it will be added automatically, and if there is an extension in the given filename, it won’t be added repeatedly;
-r: passes-rswitch to 7-zip to archive files recursively;-r0: passes-r0switch to 7-zip to archive files recursively only on filenames with wildcards; and-ep: passes-spf2switch to 7-zip to set the archive to use full paths without drive letter.
The default dictionary size is set to 1 GB, feel free to change it in line 100 (7pk.bat for Windows) or line 73 (7pk for Linux) if it is too big or too small.
A special note on using -p* to directly pass passwords to 7-zip: use "-p12,3W;SX!" to pass password 12,3W;SX! to 7-zip on Windows when using this batch; on Linux, both "-p12,3W;SX!" and -p"12,3W;SX!" would work. For passwords containing special characters or spaces, this section shall always be quoted. To avoid untold marginal cases, it is recommended to use the bare -p and let 7-zip to prompt request for a password if the password to be set is too complex.
Windows
Make sure 7-zip is installed and the location where 7-zip is installed is added to %PATH%.
| Please note that the fourth space in line 92 (the one following the second equals sign and preceding the second exclamation mark) is turned into a non-breaking space, which is not intended; this is due to an internal error by SyntaxHighlight or MediaWiki, which is not controllable by this site. Therefore, it is advised to manually replace it with a regular space before using this script in practice. |
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
for /f "tokens=1-6 delims=/: " %%a in ('robocopy "|" . /njh ^| find ":"') do set "a=%%a" & set "b=%%b" & set "c=%%c" & set "d=%%d" & set "e=%%e" & set "dt=!a:~2,2!!b!!c!-!d!!e!"
for %%I in (.) do set "dn=%%~nxI"
set "an=%dt%.7z"
set "fl="
set "pw="
set "o=0"
set "r=0"
set "ep=0"
:a
if /i "%~1"=="" goto p
if /i "%~1"=="-o" (
set "o=1"
shift
goto a
)
if /i "%~1"=="-r0" (
set "r=2"
shift
goto a
)
if /i "%~1"=="-r" (
set "r=1"
shift
goto a
)
if /i "%~1"=="-ep" (
set "ep=1"
shift
goto a
)
set "p=%~1"
if /i "%p:~0,2%"=="-p" (
set "pw=-p"%p:~2%^""
shift
goto a
)
if /i %o%==1 (
set "an=%~1"
set "o=0"
shift
goto a
)
set "fl=!fl! "%~1""
shift
goto a
:p
for /f "tokens=* delims= " %%A in ("!an!") do set "an=%%A"
for /l %%i in (1,1,32) do if /i "!an:~-1!"==" " set "an=!an:~0,-1!"
if /i "!an:~-3!"==".7z" (
set "an=!an:~0,-3!"
)
for /f "tokens=* delims= " %%A in ("!an!") do set "an=%%A"
for /l %%i in (1,1,32) do if /i "!an:~-1!"==" " set "an=!an:~0,-1!"
set "an=!an!.7z"
set "bn=!an!"
for %%P in ("!an!") do (
if /i "%%~dpP" neq "" (
set "bn=%%~nxP"
set "an=%%~dpP"
)
)
set "bn=!bn:~0,-3!"
for /f "tokens=* delims= " %%A in ("!bn!") do set "bn=%%A"
for /l %%i in (1,1,32) do if /i "!bn:~-1!"==" " set "bn=!bn:~0,-1!"
set "np=!bn!"
set "pf="
set "sf="
if /i "!np:~0,1!"=="[" (
if /i "!np:*]=!"=="!np!" (
set "np=!np:~1!"
set "pf=1"
)
)
if /i "!np:~-1!"=="_" (
set "np=!np:~0,-1!"
set "sf=1"
)
set "bn=!np!"
if defined pf (
set "bn=[!dt:~0,6!] !bn!"
)
if defined sf (
set "bn=!bn!_!dt!"
)
set "bn=!bn:`=%dn%!"
for /f "tokens=* delims= " %%A in ("!bn!") do set "bn=%%A"
for /l %%i in (1,1,32) do if /i "!bn:~-1!"==" " set "bn=!bn:~0,-1!"
:tc
set "t=!bn: = !"
if /i "!t!" neq "!bn!" (
set "bn=!t!"
goto tc
)
set "bn=!bn!.7z"
set "an=!an!!bn!"
if /i "!fl!"=="" set "fl=."
set "bc=7z a -t7z -mx=9 -aoa -mfb=273 -md=1024m -ms=on -mqs=on -mtc -mta -mtm -stl -mhe"
if /i "!ep!"=="1" (
set "bc=!bc! -spf2"
)
if /i "!r!"=="1" (
set "bc=!bc! -r"
)
if /i "!r!"=="2" (
set "bc=!bc! -r0"
)
%bc% !pw! "!an!" !fl!
endlocal
A WinRAR diversion
Make sure WinRAR is installed and the location where WinRAR is installed is added to %PATH%.
The following batch script functions very similar to the one using 7-zip above—after all, the one below is just an altered version of the one above. But it does have some exclusive features courtesy of WinRAR:
- the
-rswitch is now enabled by default, it can only be turned off if the user explicitly demands so by applying-rn,-nror simply-n—mind you, if you turns off-rwhen using WinRAR, then the application will really mean it and will not archive files recursively whatsoever, in any case, at all; it follows a logic that differs from the way 7-zip does it; - the
-epswitch obviously won’t pass-spf2to WinRAR, but the equivalent-ep2—in fact, as you can see, I named this switch in the script after the switch in WinRAR, as-pis already taken for password; and - there is a
-kswitch to ‘lock’ the archive and a-e(or-ed) switch to exclude empty folders when archiving—both are exclusive to WinRAR and cannot be achieved with 7-zip.
The default dictionary size is set to 8 GB, feel free to change it in line 127 if it is too big or too small.
| Please note that the fourth space in line 119 (the one following the second equals sign and preceding the second exclamation mark) is turned into a non-breaking space, which is not intended; this is due to an internal error by SyntaxHighlight or MediaWiki, which is not controllable by this site. Therefore, it is advised to manually replace it with a regular space before using this script in practice. |
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
for /f "tokens=1-6 delims=/: " %%a in ('robocopy "|" . /njh ^| find ":"') do set "a=%%a" & set "b=%%b" & set "c=%%c" & set "d=%%d" & set "e=%%e" & set "dt=!a:~2,2!!b!!c!-!d!!e!"
for %%I in (.) do set "dn=%%~nxI"
set "an=%dt%.rar"
set "fl="
set "pw="
set "o=0"
set "r=1"
set "k=0"
set "e=0"
set "ep=1"
:a
if /i "%~1"=="" goto p
if /i "%~1"=="-o" (
set "o=1"
shift
goto a
)
if /i "%~1"=="-rn" (
set "r=0"
shift
goto a
)
if /i "%~1"=="-n" (
set "r=0"
shift
goto a
)
if /i "%~1"=="-nr" (
set "r=0"
shift
goto a
)
if /i "%~1"=="-r0" (
set "r=2"
shift
goto a
)
if /i "%~1"=="-ed" (
set "e=1"
shift
goto a
)
if /i "%~1"=="-e" (
set "e=1"
shift
goto a
)
if /i "%~1"=="-ep" (
set "ep=2"
shift
goto a
)
if /i "%~1"=="-k" (
set "k=1"
shift
goto a
)
set "p=%~1"
if /i "%p:~0,2%"=="-p" (
set "pw=-hp"%p:~2%^""
shift
goto a
)
if /i %o%==1 (
set "an=%~1"
set "o=0"
shift
goto a
)
set "fl=!fl! "%~1""
shift
goto a
:p
for /f "tokens=* delims= " %%A in ("!an!") do set "an=%%A"
for /l %%i in (1,1,32) do if /i "!an:~-1!"==" " set "an=!an:~0,-1!"
if /i "!an:~-4!"==".rar" (
set "an=!an:~0,-4!"
)
for /f "tokens=* delims= " %%A in ("!an!") do set "an=%%A"
for /l %%i in (1,1,32) do if /i "!an:~-1!"==" " set "an=!an:~0,-1!"
set "an=!an!.rar"
set "bn=!an!"
for %%P in ("!an!") do (
if /i "%%~dpP" neq "" (
set "bn=%%~nxP"
set "an=%%~dpP"
)
)
set "bn=!bn:~0,-4!"
for /f "tokens=* delims= " %%A in ("!bn!") do set "bn=%%A"
for /l %%i in (1,1,32) do if /i "!bn:~-1!"==" " set "bn=!bn:~0,-1!"
set "np=!bn!"
set "pf="
set "sf="
if /i "!np:~0,1!"=="[" (
if /i "!np:*]=!"=="!np!" (
set "np=!np:~1!"
set "pf=1"
)
)
if /i "!np:~-1!"=="_" (
set "np=!np:~0,-1!"
set "sf=1"
)
set "bn=!np!"
if defined pf (
set "bn=[!dt:~0,6!] !bn!"
)
if defined sf (
set "bn=!bn!_!dt!"
)
set "bn=!bn:`=%dn%!"
for /f "tokens=* delims= " %%A in ("!bn!") do set "bn=%%A"
for /l %%i in (1,1,32) do if /i "!bn:~-1!"==" " set "bn=!bn:~0,-1!"
:tc
set "t=!bn: = !"
if /i "!t!" neq "!bn!" (
set "bn=!t!"
goto tc
)
set "bn=!bn!.rar"
set "an=!an!!bn!"
if /i "!fl!"=="" set "fl=."
set "bc=rar a -m5 -s -md8g -tsm -tsc -tsa -tsp -tl"
if /i "!e!"=="1" (
set "bc=!bc! -ed"
)
if /i "!ep!"=="1" (
set "bc=!bc! -ep1"
)
if /i "!ep!"=="2" (
set "bc=!bc! -ep2"
)
if /i "!r!"=="1" (
set "bc=!bc! -r"
)
if /i "!r!"=="2" (
set "bc=!bc! -r0"
)
if /i "!k!"=="1" (
set "bc=!bc! -k"
)
%bc% !pw! "!an!" !fl!
endlocal
Linux
#!/bin/bash
shopt -s nullglob
dt=$(date '+%y%m%d-%H%M')
dn=$(basename "$PWD")
an="${dt}.7z"
fl=()
pw=""
o=0
r=0
ep=0
while (( "$#" )); do
case "$1" in
-o)
o=1
shift
an="$1"
shift
;;
-p*)
pw="$1"
shift
;;
-r0)
r=2
shift
;;
-r)
r=1
shift
;;
-ep)
ep=1
shift
;;
*)
fl+=("$1")
shift
;;
esac
done
an="$(echo "$an" | sed 's/^ *//; s/ *$//')"
[[ "$an" == *.7z ]] && an="${an%.7z}"
an="$(echo "$an" | sed 's/^ *//; s/ *$//')"
an="${an}.7z"
if [[ "$an" == */* ]]; then
bn="${an##*/}"
an="${an%/*}/"
else
bn="$an"
an=""
fi
bn="${bn%.7z}"
bn="$(echo "$bn" | sed 's/^ *//; s/ *$//')"
np="$bn"
pf=0
sf=0
if [[ "$np" == \[* && "$np" != *\]* ]]; then
np="${np#[}"
pf=1
fi
if [[ "$np" == *_ ]]; then
np="${np%_}"
sf=1
fi
bn="$np"
(( pf == 1 )) && bn="[$(date '+%y%m%d')] $bn"
(( sf == 1 )) && bn="${bn}_$dt"
bn="${bn//=/$dn}"
bn="$(echo "$bn" | sed 's/^ *//; s/ *$//')"
bn="$(echo "$bn" | tr -s ' ')"
an="${an}${bn}.7z"
[[ ${#fl[@]} -eq 0 ]] && fl=(".")
bc=(7z a -t7z -mx=9 -aoa -mfb=273 -md=1024m -ms=on -mqs=on -mtc -mta -mtm -stl -mhe)
(( ep == 1 )) && bc+=(-spf2)
(( r == 1 )) && bc+=(-r)
(( r == 2 )) && bc+=(-r0)
[[ -n "$pw" ]] && bc+=("$pw")
bc+=("$an" "${fl[@]}")
"${bc[@]}"
Moreover, the latest (and official) 7-zip binary can be downloaded and put into /user/local/bin/ with the script below:
#!/bin/bash
curl https://www.7-zip.org/download.html -o /tmp/7znvdlinterim.html
href=$(grep -oP 'href="a/7z[0-9]{4}-linux-x64\.tar\.xz"' /tmp/7znvdlinterim.html | head -n 1 | cut -d'"' -f2)
url="https://www.7-zip.org/$href"
curl -L -o /tmp/7znvdlinterim.tar.xz "$url"
tar -xJf /tmp/7znvdlinterim.tar.xz -C /tmp/ --transform='s/7zz/7znvdlinterim/' 7zz
sudo install -m 755 /tmp/7znvdlinterim /usr/local/bin/7z
rm -rf /tmp/7znvdlinterim*
And the other one
(Translated by Grok, not fully tested, should be fine.)
#!/bin/zsh
setopt NULL_GLOB
dt=$(date '+%y%m%d-%H%M')
dn=$(basename "$PWD")
an="${dt}.7z"
fl=()
pw=""
o=0
r=0
ep=0
while (( $# )); do
case "$1" in
-o)
o=1
shift
an="$1"
shift
;;
-p*)
pw="$1"
shift
;;
-r0)
r=2
shift
;;
-r)
r=1
shift
;;
-ep)
ep=1
shift
;;
*)
fl+=("$1")
shift
;;
esac
done
an="$(echo "$an" | sed 's/^ *//; s/ *$//')"
[[ "$an" == *.7z ]] && an="${an:r}"
an="$(echo "$an" | sed 's/^ *//; s/ *$//')"
an="${an}.7z"
if [[ "$an" == */* ]]; then
bn="${an:t}"
an="${an:h}/"
else
bn="$an"
an=""
fi
bn="${bn:r}"
bn="$(echo "$bn" | sed 's/^ *//; s/ *$//')"
np="$bn"
pf=0
sf=0
if [[ "$np" == \[* && "$np" != *\]* ]]; then
np="${np#[}"
pf=1
fi
if [[ "$np" == *_ ]]; then
np="${np%_}"
sf=1
fi
bn="$np"
(( pf == 1 )) && bn="[$(date '+%y%m%d')] $bn"
(( sf == 1 )) && bn="${bn}_$dt"
bn="${bn//=/$dn}"
bn="$(echo "$bn" | sed 's/^ *//; s/ *$//')"
bn="$(echo "$bn" | tr -s ' ')"
an="${an}${bn}.7z"
[[ ${#fl[@]} -eq 0 ]] && fl=(".")
bc=(7z a -t7z -mx=9 -aoa -mfb=273 -md=1024m -ms=on -mqs=on -mtc -mta -mtm -stl -mhe)
(( ep == 1 )) && bc+=(-spf2)
(( r == 1 )) && bc+=(-r)
(( r == 2 )) && bc+=(-r0)
[[ -n "$pw" ]] && bc+=("$pw")
bc+=("$an" "${fl[@]}")
"${bc[@]}"