How to *Only* Get the Number of Bytes Available on a Disk in Bash

How can I *only* get the number of bytes available on a disk in bash?

Portably:

df -P /dev/sda1 | awk 'NR==2 {print $4}'

The -P option ensures that df will print output in the expected format, and will in particular not break the line after the device name even if it's long. Passing the device name as an argument to df removes any danger from parsing, such as getting information for /dev/sda10 when you're querying /dev/sda1. df -P just prints two lines, the header line (which you ignore) and the one data line where you print the desired column.

There is a risk that df will display a device name containing spaces, for example if the volume is mounted by name and the name contain spaces, or for an NFS volume whose remote mount point contains spaces. In this case, there's no fully portable way to parse the output of df. If you're confident that df will display the exact device name you pass to it (this isn't always the case), you can strip it:

df -P -- "$device" | awk -vn=${#device} 'NR==2 {$0 = substr($0, n+1); print $3}'

Get free disk space with df to just display free space in kb?

To get the output of df to display the data in kb you just need to use the -k flag:

df -k

Also, if you specify a filesystem to df, you will get the values for that specific, instead of all of them:

df -k /example

Regarding the body of your question: you want to extract the amount of free disk space on a given filesystem. This will require some processing.

Given a normal df -k output:

$ df -k /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 7223800 4270396 2586456 63% /

You can get the Available (4th column) for example with awk or cut (previously piping to tr to squeeze-repeats (-s) for spaces):

$ df -k /tmp | tail -1 | awk '{print $4}'
2586456
$ df -k /tmp | tail -1 | tr -s ' ' | cut -d' ' -f4
2586456

As always, if you want to store the result in a variable, use the var=$(command) syntax like this:

$ myUsed=$(df -k /tmp | tail -1 | awk '{print $4}')
$ echo "$myUsed"
2586456

Also, from the comment by Tim Bunce you can handle long filesystem names using --direct to get a - instead, so that it does not print a line that breaks the engine:

$ df -k --direct /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
- 7223800 4270396 2586456 63% /

How to get only the first ten bytes of a binary file

To get the first 10 bytes, as noted already:

head -c 10

To get all but the first 10 bytes (at least with GNU tail):

tail -c+11

How can I substring a specific number of bytes from a string in PowerShell?

To answer the base question "How can I substring a specific number of bytes from a string in PowerShell", I was able to write the following function:

function Get-SubstringByByteCount {
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[ValidateScript({ $null -ne $_ -and $_.Value -is [string] })]
[ref]$InputString,
[int]$FromIndex = 0,
[Parameter(Mandatory)]
[int]$ByteCount,
[ValidateScript({ [Text.Encoding]::$_ })]
[string]$Encoding = 'UTF8'
)

[long]$byteCounter = 0
[System.Text.StringBuilder]$sb = New-Object System.Text.StringBuilder $ByteCount

try {
while ( $byteCounter -lt $ByteCount -and $i -lt $InputString.Value.Length ) {
[char]$char = $InputString.Value[$i++]
[void]$sb.Append($char)
$byteCounter += [Text.Encoding]::$Encoding.GetByteCount($char)
}

$sb.ToString()
} finally {
if( $sb ) {
$sb = $null
[System.GC]::Collect()
}
}
}

Invocation works like so:

Get-SubstringByByteCount -InputString ( [ref]$someString ) -ByteCount 8

Some notes on this implementation:

  • Takes the string as a [ref] type since the original goal was to avoid copying the full string in a limited-memory scenario. This function could be re-implemented using the [string] type instead.
  • This function essentially adds each character to a StringBuilder until the specified number of bytes has been written.
  • The number of bytes of each character is determined by using one of the [Text.Encoding]::GetByteCount overloads. Encoding can be specified via a parameter, but the encoding value should match one of the static encoding properties available from [Text.Encoding]. Defaults to UTF8 as written.
  • $sb = $null and [System.GC]::Collect() are intended to forcibly clean up the StringBuilder in a memory-constrained environment, but could be omitted if this is not a concern.
  • -FromIndex takes the start position within -InputString to begin the substring operation from. Defaults to 0 to evaluate from the start of the -InputString.

How to get the sizes of the tables of a MySQL database?

You can use this query to show the size of a table (although you need to substitute the variables first):

SELECT 
table_name AS `Table`,
round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB`
FROM information_schema.TABLES
WHERE table_schema = "$DB_NAME"
AND table_name = "$TABLE_NAME";

or this query to list the size of every table in every database, largest first:

SELECT 
table_schema as `Database`,
table_name AS `Table`,
round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB`
FROM information_schema.TABLES
ORDER BY (data_length + index_length) DESC;

Portable way to get file size (in bytes) in the shell

wc -c < filename (short for word count, -c prints the byte count) is a portable, POSIX solution. Only the output format might not be uniform across platforms as some spaces may be prepended (which is the case for Solaris).

Do not omit the input redirection. When the file is passed as an argument, the file name is printed after the byte count.

I was worried it wouldn't work for binary files, but it works OK on both Linux and Solaris. You can try it with wc -c < /usr/bin/wc. Moreover, POSIX utilities are guaranteed to handle binary files, unless specified otherwise explicitly.



Related Topics



Leave a reply



Submit